home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / faq / computer-lang / java / programmers / faq.z / faq
Internet Message Format  |  1999-01-01  |  378KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kodak.com!news-nysernet-16.sprintlink.net!news-backup-east.sprintlink.net!news.sprintlink.net!128.122.253.90!newsfeed.nyu.edu!newshub.northeast.verio.net!news1.best.com!news3.best.com!nntp1.ba.best.com!not-for-mail
  2. From: pvdl@best.com (Peter van der Linden)
  3. Newsgroups: comp.lang.java.programmer,comp.lang.java.help,comp.lang.java.gui,comp.answers,news.answers
  4. Subject: Java Programmers FAQ
  5. Supersedes: <6vlf3m$r6n$1@shell15.ba.best.com>
  6. Followup-To: poster
  7. Date: 17 Oct 1998 16:54:10 -0700
  8. Approved: news-answers-request@MIT.EDU
  9. Message-ID: <70ban2$ak8$1@shell15.ba.best.com>
  10. Summary: This posting answers frequently-asked questions by Java programmers
  11. Lines: 8533
  12. NNTP-Posting-Host: shell15.ba.best.com
  13. X-Trace: 908668457 3286 pvdl 206.184.139.147
  14. Xref: senator-bedfellow.mit.edu comp.lang.java.programmer:162445 comp.lang.java.help:33873 comp.lang.java.gui:20675 comp.answers:33481 news.answers:142336
  15.  
  16. Archive-name: computer-lang/java/programmers/faq
  17. Posting-Frequency: weekly
  18. Last-modified: 1998/10/17
  19. URL: http://www.afu.com/javafaq.html
  20.  
  21. Frequently Asked Questions (with answers) for Java programmers
  22.  
  23.            _____________________________________________________
  24.   ________|                                                     |________
  25.   \       |   Java Programmers FAQ         http://www.afu.com   |       /
  26.    \      |   Last modified Oct 17, 1998   Peter van der Linden |      /
  27.    /      |_____________________________________________________|      \
  28.   /___________)                                              (__________\
  29.  
  30. The Java FAQs here are intended for people who already have some programming
  31. experience, though maybe not in Java.
  32.  
  33. Go to the FAQ home page at http://www.afu.com for other Java information and
  34. downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to
  35. faqidea at the address afu.com.
  36.  
  37. ------------------------------------------------------------------------
  38.  
  39. Specify standard Java on your new PC!
  40.  
  41.         Your new PC can come with the most up-to-date standard version of
  42.         Java, but only if you ask for it! The JavaLobby is asking PC vendors
  43. to support Java, and to ship new machines with the Java Plug-In
  44. pre-installed.
  45.  
  46. See http://www.javalobby.org/servlet/PetitionServlet/pjpc
  47. Please help the Java Lobby to promote this initiative.
  48.  
  49. ------------------------------------------------------------------------
  50.  
  51. Please support Java Portability.
  52.  
  53. The biggest value of Java is its portability.
  54.  
  55.    * Portability makes it easier for companies to change/upgrade operating
  56.      systems and platforms, without losing their investment in applications
  57.      software.
  58.    * Portability makes it easier for Java programmers to transfer their
  59.      skills to new employers.
  60.    * Portability makes a wider variety of software available on all
  61.      computers.
  62.  
  63. Software portability is very much in the interest of most software
  64. developers and customers. Even if you only use Windows 95, portability
  65. matters to you. If your software was all written in Java, it would all just
  66. run when you moved from MS-DOS to Windows 3.1 to Windows 95 to Windows 98 to
  67. Windows NT, and even on Windows CE. Instead, you typically need to buy new
  68. applications software all over again when Windows changes. Portability is
  69. not in Microsoft's interest, as it removes a revenue stream and makes it
  70. easy for users to try other operating systems.
  71.  
  72. The 1998 anti-monopoly case against Microsoft revealed a Microsoft internal
  73. memo. The memo stated that Microsoft's strategic goal was to "kill
  74. cross-platform Java." If portability matters to you or your users, avoid
  75. Java products from Microsoft; it is deliberately undermining it. See
  76. http://www.usdoj.gov/atr/cases/f1700/1762.htm.
  77.  
  78.                        -------------------------------
  79.  
  80. The sections of the Java FAQ are:
  81.  
  82.    * Portability
  83.    * 1. Java Book Information
  84.    * 2. General Information
  85.    * 3. Compilers and Tools
  86.    * 4. Getting Started
  87.    * 5. Compiler Messages
  88.    * 6. Java Language issues
  89.    * 7. I/O
  90.    * 8. Core library issues
  91.    * 9. Computer Dating
  92.    * 10. AWT
  93.    * 11. Swing
  94.    * 12. Browsers
  95.    * 13. Applets
  96.    * 14. Multi-Media
  97.    * 15. Networking
  98.    * 16. Security
  99.    * 17. For C, C++ Afficionados
  100.    * 18. Java Idioms
  101.    * 19. Java Gotcha's
  102.    * 20. Further Resources
  103.    * 21. Acknowledgements
  104.  
  105.                        -------------------------------
  106.  
  107. 1. Java Book Information
  108.  
  109.   1. (sect. 1) Learning Java
  110.  
  111.      [*] The Java FAQ is maintained as a service to the Java community. Java
  112.      is a great language, and everyone benefits when newcomers get a helping
  113.      hand.
  114.      Please consider these books from the FAQ author when you are looking
  115.      for a programming text.
  116.         o "Just Java 1.1" Java, for people who can already program in
  117.           another language.
  118.           More at http://www.amazon.com/exec/obidos/ISBN%3D0137841744
  119.  
  120.           Comments from a reader: "Just Java 1.1 is a great book! Before I
  121.           bought it, I had a couple of other books that were OK, but I kept
  122.           going back to the bookstore to check "Just Java 1.1" whenever some
  123.           aspect of the language was unclear. Invariably the Just Java
  124.           explanations were lucid and to the point. I just had to get it."
  125.  
  126.         o "Not Just Java" Java explained for managers and the rest of us.
  127.           More info at http://www.amazon.com/exec/obidos/ISBN=0138646384
  128.           Comment from readers: "...An excellent overview of the IT maze"
  129.           "... Not Just Java lets readers educate themselves on where we
  130.           are, and where we're going."
  131.           "This book describes, with graphical illustrations, the emerging
  132.           new ideas and how to use them."
  133.  
  134.      Sample chapters are on Sun Microsystems' webpage at
  135.      http://www.sun.com/971124/cover-linden/.
  136.  
  137.   2. (sect. 1) How do I choose a Java book?
  138.  
  139.      [*] There is no one right answer to "which is the right Java book for
  140.      me?" It all depends on what you already know and how you like to learn.
  141.      Here are the points to check when evaluating a programming book.
  142.         o Above all, make sure that it is a Java book. If it comes with a
  143.           CD, check that it has a Java compiler on it, not a J++ compiler.
  144.           J++ is a different language in some small but important ways, and
  145.           is missing several of the key Java libraries.
  146.           If your interest is Java, leave the J++ book back on the shelf.
  147.         o Check that the book has a reasonable number of figures, diagrams,
  148.           and illustrations. It is not possible to explain how to program a
  149.           window system without pictures and diagrams. Other topics benefit
  150.           from pictures, too.
  151.         o Check what the book says about itself. Is it a reference work,
  152.           intended for Java-experts to look things up in? This is the role
  153.           of "Java in a Nutshell", and "The Java Almanac". Do you need that,
  154.           or are you looking for a book that teaches by examples and
  155.           explanations?
  156.         o Programming is one of those things that you learn by doing. Check
  157.           that each chapter has exercises, preferably with answers. You'll
  158.           need to do the exercises to learn the language.
  159.         o Does the book cover the current level of Java, which is Java 1.1
  160.           (with 1.2 in Beta). Look up "FileWriter" in the index. If it's not
  161.           there, you probably want a more modern book. Look up "JApplet" in
  162.           the index. If it's not there, the book doesn't cover JDK 1.2.
  163.         o Appraise your own level of programming knowledge: are you
  164.           proficient in some other language, or are you learning programming
  165.           as well? Does the book cater to your needs?
  166.         o Read a section of the book. Does the style keep you interested, as
  167.           it educates you? Will you get bored if you read many pages? Is the
  168.           book too long for your initial purpose? Browse Amazon online and
  169.           see what other readers say about the text.
  170.         o If the book comes with a CD, how much other software is on the CD?
  171.           You want at least a Java compiler plus all the examples from the
  172.           book. Does the Java compiler work on your platform (Mac, Linux,
  173.           etc)? Additional software on the CD is a big plus, as we learn the
  174.           most from reading other people's code.
  175.      Probably no one book is perfect for anyone. Most people buy one to
  176.      begin with, then four or five more as they wish to learn more, and
  177.      about more up-to-date topics. The FAQ author has purchased and read
  178.      probably 60 Java books in the last three years.
  179.  
  180.   3. (sect. 1) Where can I find a some lists of Java books and book reviews?
  181.  
  182.      [*] Here are some good ones:
  183.      http://www.flathill.com/languages/java/
  184.      also
  185.      http://teamjava.com/links/tj-srv.cgi?MUF=0,tj-booklist.muf
  186.      also
  187.      http://www.javaworld.com/javaworld/books/jw-books-index.html
  188.      (an exhaustive list -- takes a long time to load).
  189.  
  190.                        -------------------------------
  191.  
  192. 2. General Information
  193.  
  194.   1. (Sect. 2) Is Java "Open" or "Proprietary"?
  195.  
  196.      [*] The Java specification is publicly available, and anyone is free to
  197.      do clean-room implementations of the JVM and core Java API's. Sun
  198.      includes a perpetual, irrevocable, free and royalty-free license in the
  199.      front of the Addison-Wesley books containing the specification.
  200.  
  201.      Sun also provides free access to the Java source. If you aren't
  202.      planning on using the results in a commercial product, or doing any
  203.      sort of external redistribution, there is an Internal Noncommercial Use
  204.      Source License available at no charge. Please see
  205.      http://java.sun.com/nav/business/source_form.html
  206.  
  207.      Using the Java trademark does requires licensing from Sun. It is not
  208.      clear if the Embedded or Personal Java specifications are open, as it
  209.      is not clear if a clean-room implementation may be done without
  210.      licensing from Sun.
  211.  
  212.      The relative openness of Java contrasts with systems that are only
  213.      available from one vendor, whose interfaces are developed in secret,
  214.      without an open process for others to participate, whose owners do not
  215.      allow competing implementations of the same API, and whose owners
  216.      change the APIs as a strategic weapon against competitors. Typically,
  217.      such systems also feature "private" APIs that are published late or not
  218.      published at all, to allow the single vendor to gain a competitive
  219.      advantage for their other products. Typically such proprietary systems
  220.      do not make the source code available for inspection by all.
  221.  
  222.   2. (Sect. 2) What is the best way to refer someone to the FAQ when they
  223.      ask a question I know is answered there?
  224.  
  225.      [*] The Java Programmers FAQ (at http://www.afu.com) answers your
  226.      question in section N.n. ...
  227.  
  228.      This gives them the answer, and shows them where to go for future
  229.      questions. It also demonstrates that the FAQ can answer their
  230.      questions, supplying an incentive to go there next time. It's regarded
  231.      as elementary politeness to look for the FAQ of a newsgroup and read it
  232.      before posting any questions.
  233.  
  234.      In general, FAQs for any newsgroup are available by looking at past
  235.      postings in a group, or by searching Deja News (see Q 1.4), or via
  236.      anonymous FTP at directories under ftp://rtfm.mit.edu. The pathnames
  237.      are called things like
  238.      /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ
  239.      which may help you get to the right one directly, as it takes some time
  240.      to get a directory listing there. Alternatively, you can look for
  241.      newsgroup names on the same ftp site by going to the same site and
  242.      looking under /pub/usenet-by-hierarchy/. That has subdirectories such
  243.      as alt/, ba/, ca/, comp/, and subdirectories under them such as
  244.      /pub/usenet-by-hierarchy/comp/lang/ and so on. This helps you explore
  245.      the world of newsgroups with FAQs.
  246.  
  247.      If you do not have anonymous FTP access, you can access the
  248.      rtfm.mit.edu archives by mail server as well. Send an E-mail message to
  249.      mail-server@rtfm.mit.edu with "help" in the body for more information.
  250.      "RTFM" stands for "Read The effing Manual" - you must expect to put in
  251.      some time and effort to master a new area of study.
  252.  
  253.      If you want to look at the definition of Internet standards like FTP,
  254.      telnet, visit the IETF site at http://www.ietf.org where all the RFC's
  255.      (Request For Comments) can be found.
  256.  
  257.   3. (Sect. 2) What if my question is not answered in this FAQ?
  258.  
  259.      [*] Go to http://www.dejanews.com/home_ps.shtml
  260.         o Under "Newsgroups" enter "comp.lang.java.programmer" (or whatever)
  261.         o Under "Subject" enter "Frotteur" (or other topic you find
  262.           pressing)
  263.         o Click "Create Filter"
  264.         o It will go to a new document, and you should click the link
  265.           labeled
  266.  
  267.           nnn Documents (nnn is some number).
  268.  
  269.      The chances are that you will find several answers to your question.
  270.      Some may not be complete or completely accurate however. That is the
  271.      nature of Usenet, and free information. If you still don't have an
  272.      answer, then post your question on the most appropriate of the
  273.      newsgroups. Don't spam the newsgroups by posting to multiple groups.
  274.      Knowledgeable posters tend to ignore questions like that.
  275.  
  276.      Also look at http://sunsite.unc.edu/java/cgi-bin/query
  277.      and look at http://asknpac.npac.syr.edu/ for a Java newsgroup search.
  278.  
  279.      http://www.javaworld.com/search.html can search the Javaworld
  280.      newspaper.
  281.  
  282.   4. (Sect. 2) What Java mailing lists are there?
  283.  
  284.      [*] There are quite a few Java mailing lists.
  285.      http://java.miningco.com/msub7.htm has a comprehensive list.
  286.  
  287.   5. (Sect. 2) Where can I look at the definitive Java Language
  288.      Specification?
  289.  
  290.      [*] This is available online at:
  291.           http://java.sun.com/docs/books/jls/html/index.html (Java 1.0)
  292.  
  293.      and the Java 1.1 inner classes document at:
  294.           http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/
  295.           spec/innerclasses.doc.html
  296.  
  297.      and the other Java 1.1 update at:
  298.           http://java.sun.com/docs/books/jls/html/1.1Update.html
  299.  
  300.      and the Java API is at:
  301.           http://java.sun.com/products/jdk/1.1/docs/api
  302.  
  303.      It is also available as a book in printed form (details at website).
  304.      Also see the "Clarifications and Amendments"
  305.      http://java.sun.com/docs/books/jls/clarify.html.
  306.  
  307.      You can also see the virtual machine (execution environment)
  308.      specification at
  309.      http://docs.sun.com:80/ab2/java1/@Ab2CollToc?subject=java
  310.  
  311.   6. (Sect. 2) Where can I find information about future Java APIs?
  312.  
  313.      [*] JavaSoft has followed a policy of creating new APIs in consultation
  314.      with leading industry participants, then posting the draft
  315.      specification for public review and comments. Check the JavaSoft
  316.      roadmap of new APIs and products at
  317.      http://java.sun.com:80/products/api-overview/index.html
  318.      Also, some APIs that are under consideration, possibly for JDK 1.2 are
  319.      at:
  320.           http://java.sun.com/products/jdk/preview/docs/
  321.  
  322.   7. (Sect. 2) I'm looking for a Java style guide on naming conventions.
  323.  
  324.      [*] Check out the section "Naming Conventions" in the language
  325.      specification
  326.           http://java.sun.com/docs/books/jls/html/6.doc.html#11186
  327.  
  328.      Also take a look at Doug Lea's draft coding standard -
  329.           http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
  330.  
  331.      See also naming conventions for some basic rules of thumb.
  332.  
  333.   8. (Sect. 2) How do I check on known bugs in the JDK?
  334.  
  335.      [*] Look at the Java Developer Connection at http://java.sun.com/jdc.
  336.  
  337.      All the Java bugs that Sun knows about are listed there, with the
  338.      exception of security-related bugs. The legal department in Sun vetoed
  339.      the open publication of security bugs. After you have checked that the
  340.      bug is not already listed, you can submit a bug report through:
  341.      http://java.sun.com:80/cgi-bin/bugreport.cgi
  342.      You should check that the bug doesn't already exist for two reasons:
  343.      first, you might find the bug with a workaround listed. Second, you
  344.      don't want to waste everyone's time with a duplicate bug report.
  345.  
  346.      You can also send in an RFE (Request For Enhancement) or ease-of-use
  347.      issue there. You can even vote on the priority you would assign to a
  348.      particular bug fix! Join the Java Developer Connection (it's free) by
  349.      going to http://java.sun.com/jdc. Then browse
  350.      http://developer.javasoft.com/developer/bugParade/#votes
  351.  
  352.   9. (Sect. 2) What computers have Java ports? Is there a port to Win 3.1?
  353.  
  354.      [*] A partial list of JDK ports is available from
  355.      http://java.sun.com/cgi-bin/java-ports.cgi
  356.      An (impressive) list of the systems that the GPL Kaffee JVM runs on is
  357.      at http://www.transvirtual.com/ports.html
  358.  
  359.      There are several Java ports to Win 3.1. IBM's ADK1.02 is available at
  360.      the following locations:
  361.         o http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html
  362.         o http://www.alphaworks.ibm.com/formula
  363.      IBM offers a port to Linux, as do others. The IBM Jikes port is at
  364.      http://www.alphaworks.ibm.com/ There is a large amount of useful
  365.      software there, including a profiling tool called jinsight (caveat: it
  366.      may not work with all releases of JDK 1.1, i.e. not JDK 1.1.6).
  367.  
  368.      Netscape Navigator for Win3.1 has Java support. Java will never be
  369.      well-supported under Win3.1 because Win3.1 lacks the basic features
  370.      expected of a modern OS (primarily lengthy filenames and multithreading
  371.      support).
  372.  
  373.      Also take a look at JavaSoft's JavaPC kit that can switch a PC into a
  374.      thin client Java system (and back to Win3.1/DOS when you want). It's
  375.      meant for software OEMs and large corporations running lots of older
  376.      PCs, but you can use it on the latest Pentium II too. Details are at
  377.      http://java.sun.com/products/javapc/index.html. JavaPC is available now
  378.      for $100, runs on 486's with 8Mb or more Unlike the 16-bit versions of
  379.      Netscape Navigator and Microsoft Internet Explorer, which provide a
  380.      Java Virtual Machine that is only compliant with the JDK 1.0.2 API, the
  381.      JavaPC software allows IS managers to deploy JDK 1.1-compatible Java
  382.      applications on PCs running DOS and Windows 3.x.
  383.  
  384.  10. (Sect. 2) Where can I find information on Java 3D?
  385.  
  386.      [*] The Java 3D FAQ at http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html
  387.      may have the answers you're looking for. It contains general
  388.      information about Java 3D, as well as programming tips.
  389.  
  390.  11. (Sect. 2) Where can I find information about Java Certification?
  391.  
  392.      [*] Sun is sponsoring an examination which programmers worldwide can
  393.      take. Those passing can use the designation "Sun Certified Java
  394.      Programmer". There is also a second-level test, involving writing a
  395.      program to spec, and taking a further test. That results in the
  396.      qualification "Sun Certified Java Developer". You can find out all
  397.      about the exam at:
  398.           http://www.sun.com/service/suned/
  399.  
  400.      and then search for "sun certified java". It costs $150 to sit the Java
  401.      Programmer exam. It is not trivial to pass the Java certification exam.
  402.      It requires understanding the objectives of the test, and the material
  403.      that is tested for. These are given, along with sample questions, at
  404.      the URL mentioned above.
  405.  
  406.  12. (Sect. 2) How can I find links to recent news about Java?
  407.  
  408.      [*] This site contains links to late-breaking online news stories about
  409.      Java. http://www.intelligence.com/java/
  410.      Another good Java news source is http://www.nikos.com/javatoys.
  411.  
  412.      This site is a fine site for programmers who want to be well-informed
  413.      about computer industry topics. It has a lot of coverage of Linux as
  414.      well as more general news. http://slashdot.org Highly recommended.
  415.  
  416.      This site is a source of independent news and commentary on the
  417.      computer industry, including Java. http://www.pjprimer.com/media.html.
  418.      You have to subscribe ($10/year, 30 day free trial).
  419.  
  420.  13. (Sect. 2) What are the folks at GNU doing with Java?
  421.  
  422.      [*] First note that the URLs in this section change quickly, and soon
  423.      become outdated. If you have an update, send it in. There is a Gnu Java
  424.      page at http://www.gnu.org/software/java/java.html
  425.      Guava (a GPL'd Java compiler) can be found at
  426.           ftp://ftp.yggdrasil.com/pub/dist/devel/compilers/guavac/
  427.      Alternatively, it may be available at
  428.      http://http.cs.berkeley.edu/~engberg/guavac
  429.      Work is progressing on the Cygnus Java frontend to gcc. See
  430.      http://www.cygnus.com/product/javalang/
  431.  
  432.      Kaffe (a JVM) can be found at
  433.           http://www.transvirtual.com This is Tim Wilkenson's company
  434.           devoted to commercializing the Kaffe JVM for the embedded systems
  435.           market. He also releases a version of it under the GPL. It also
  436.           comes with a the beginnings of a class library and the Pizza
  437.           compiler.
  438.  
  439.      Classpath is a free implementation of Sun's core Java libraries (v1.1),
  440.      being developed for the GNU Project ( http://www.gnu.org). Information
  441.      regarding classpath is at http://www.classpath.org They aim to develop
  442.      a 100% free drop in replacement for Sun's class libraries, targeting
  443.      first the Japhar JVM (below). They are always looking for help, so feel
  444.      free to stop by and volunteer.
  445.  
  446.      See also http://www.japhar.org This is the Hungry Programmer's JVM.
  447.      Currently it is development grade only.
  448.  
  449.  14. (Sect. 2) What is "San Francisco"?
  450.  
  451.      [*] San Francisco is the code name for a very large Java project led by
  452.      IBM, and involving other companies. The project is to provide a Java
  453.      framework for data processing applications. A large number of classes
  454.      are provided for general ledger, sales order, inventory management,
  455.      etc., and these classes can be extended and customized for particular
  456.      industries (vertical markets). It is a large and ambitious software
  457.      project.
  458.  
  459.      IBM's SF project competes with products from companies like SAP and
  460.      Baan. Of course, the SF project is multi-platform and uses Java beans
  461.      and GUI interfaces. More information on SF is available at
  462.      http://www.ibm.com/Java/Sanfrancisco
  463.  
  464.  15. (Sect. 2) What large Office-style or other applications have been
  465.      written in Java?
  466.  
  467.      [*] Well, the first one to consider is IBM's San Francisco project,
  468.      mentioned above. There is also Lotus's e-suite - a suite of Java
  469.      applets and beans including a spreadsheet and a word processor. See
  470.      http://esuite.lotus.com. These became available in March 1998.
  471.  
  472.      Another office suite in Java is Applix Anyware at
  473.      http://www.applix.com/anyware/index.htm. Applix became available in
  474.      downloadable demo form in April 1998.
  475.  
  476.      Yet another is Star Division's Client/Server Office. It is an office
  477.      suite with the client part written in Java and able to run on
  478.      JavaStations. The server part will run on Solaris, NT, OS/390, and
  479.      AS/400. The older (non-Java) version is bundled with all Sun
  480.      workstations sold in Germany. The Linux version is freely downloadable
  481.      from http://www.stardivision.com.
  482.  
  483.      Another is Digital Harbor's Wav word processor. It supports component
  484.      software, and it runs in 1MB, not the 114Mb of the latest MS Word. A
  485.      free trial is avilable. See: http://www.digitalharbor.com
  486.  
  487.      Another Java application is Formula One for Java, an Excel-compatible
  488.      spreadsheet written in 100% pure Java, and available for all systems
  489.      that support Java. It runs as a Java Bean, so can easily be assembled
  490.      as one component of a larger system. Formula One is a product of Visual
  491.      Components, Inc. See http://www.f1j.com.
  492.  
  493.      Another one is Ncode Research Inc. who write Java viewers for office
  494.      suites. They are file-format specialists. Their mission is to make all
  495.      popular file formats available for the Java platform. They write 100%
  496.      Pure Java viewers for Word, Excel and PowerPoint (including Office 95
  497.      and 97 formats). See http://www.ncode.com/
  498.      Another company operating in the same space is JSoft, at
  499.      http://www.jsoftinc.com
  500.  
  501.      The niche for single-user office productivity applications is pretty
  502.      well already dominated by Microsoft products, and it is unrealistic to
  503.      think that Java software will unseat shrink-wrapped software simply
  504.      because it is written in Java. This is why Corel replanned its Java
  505.      rewrite of Corel Office before taking it to FCS. When Corel did that,
  506.      it also increased its investment in Java from 33% of R&D budget to 50%,
  507.      at the expense of Windows.
  508.  
  509.      Most of Java development is taking place for custom applications
  510.      internal to a company. Most programmers of any kind have never worked
  511.      on MS Office, but work on internal applications, and so it is with
  512.      Java. These projects don't have the high profile of major vendors'
  513.      products, but they are the mainstay of the industry. There are many
  514.      companies working on Java Beans, like http://www.quadbase.com who have
  515.      Java graphing software. EspressChart is a Java Bean that gives you the
  516.      ability to add 2D and 3D graphs in your applications/applets. This bean
  517.      is easy to use, 100% Java, and runs anywhere.
  518.  
  519.      There are some good Java games applets at
  520.      http://www.frontiernet.net/~imaging/java_games.html
  521.      If you want to use Java to learn math & computer graphics, visit
  522.      http://www.frontiernet.net/~imaging/math_is_a_game.html
  523.  
  524.      Finally, note that Sun's Java compiler is written in Java. This is a
  525.      really big application in widespread use on millions of platforms. The
  526.      compile command "javac test.java" is equivalent to
  527.  
  528.          java sun.tools.javac.Main test.java
  529.  
  530.  
  531.      javac has a script wrapper just to set the heap size as a command line
  532.      argument, as you can do in your own programs.
  533.  
  534.  16. (Sect 2.) What Java User Groups are there?
  535.  
  536.      [*] There are scores of Java User groups around the world, mostly in
  537.      urban areas, and centers of software technology development. A partial
  538.      list with contact information can be found at
  539.      http://sunsite.unc.edu/javafaq/usergroups.html.
  540.  
  541.      If you can't find a user group in your area/school, it's easy and
  542.      satisfying to start one.
  543.  
  544.  17. (Sect 2.) What is a Java Bean?
  545.  
  546.      [*] A Java bean is a Java class that follows some simple conventions.
  547.      Because it follows conventions, it can easily be processed by a
  548.      software tool that connects Beans together. Java beans are reusable
  549.      software components.
  550.  
  551.      Think of Java beans as being the software equivalent of Lego[tm]
  552.      bricks. Instead of plugging together plastic bricks, you can easily
  553.      plug together classes, and have them fit and work with each other. See
  554.      http://www.jc100.org/
  555.      See the Java Bean FAQ at http://java.sun.com/beans/faq/faq.general.html
  556.  
  557.  18. (Sect 2.) Where can I find examples of the use of the Java class
  558.      libraries?
  559.  
  560.      [*] The two volumes of "Java Class Libraries" by Chan, Lee and Krama
  561.      published by Addison Wesley, have extensive examples of how to use the
  562.      standard libraries. One programmer comments "When I need to use an
  563.      unfamiliar area of the class libraries one of the first things I do is
  564.      read their examples." You can see them online at
  565.      http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html
  566.      and http://java.sun.com/docs/books/chanlee/second_edition/examples.html
  567.  
  568.                        -------------------------------
  569.  
  570. 3. Compilers and Tools
  571.  
  572.   1. (Sect. 3) Is there a lex and yacc or preferably a flex and bison
  573.      equivalent for Java?
  574.  
  575.      [*] There is a lex equivalent called JavaLex and a yacc equivalent
  576.      called CUP.
  577.  
  578.      LALR(1) parser JavaLex and JavaCup:
  579.      http://www.cs.princeton.edu/~appel/modern/java/
  580.  
  581.      LL(k) parser JavaCC: http://www.suntest.com/JavaCC/
  582.      LALR(1) parser SableCC from McGill U.
  583.      http://www.sable.mcgill.ca/sablecc/index.html is generously made
  584.      available under GNU license.
  585.  
  586.   2. (Sect. 3) Where can I find a byte code obfuscator?
  587.  
  588.      [*] There is a commercially supported obfuscator, with a downloadable
  589.      free trial at http://www.4thpass.com/SourceGuard. There are also some
  590.      free works from students and others. http://www.primenet.com/~ej/
  591.      http://www.math.gatech.edu/~mladue/HoseMocha.java
  592.  
  593.      Some people have reported problems using these with JDK 1.1.
  594.  
  595.      This obfuscator has been updated to be fully compatible with JDK 1.1:
  596.      http://www.monmouth.com/~neil/Obfuscate.html
  597.  
  598.      Obfuscators are intended to foil decompilers. Decompilers translate
  599.      byte code back into Java source code. Mocha was the first and most well
  600.      known of the decompilers; it's no longer supported. There is a
  601.      decompiler (written in C++) at
  602.           http://web.unicom.com.cy/~kpd/jad.html
  603.      Because it is in C++, there are different versions for every
  604.      architecture (hah!) There are also commercial products, such as
  605.      SourceAgain from
  606.           http://www.ahpah.com/
  607.  
  608.      There's a very good Java Code Engineering and Reverse Engineering FAQ
  609.      page at http://Meurrens.ML.org/ip-Links/Java/codeEngineering/.
  610.  
  611.   3. (Sect. 3) Which program is used to create .zip files compatible with
  612.      the java* programs?
  613.      (e.g. classes.zip, moz3_0.zip)
  614.  
  615.      [*] Use the jar-tool from JDK1.1(.1):
  616.           jar [ options ] [manifest] destination input-file [input-files]
  617.  
  618.      E.g.:
  619.           jar cvf myJarFile.jar *.class
  620.  
  621.      creates a compressed archive
  622.           jar cvfO myJarFile.zip *.class
  623.  
  624.      creates it fullsize (uncompressed) (note the 'O'-option used for
  625.      JDK1.0.2)
  626.  
  627.      On Unix you can also use:
  628.           zip -rn ".class" my_file.zip *
  629.  
  630.      Info-ZIP home page: http://www.cdrom.com/pub/infozip/
  631.      Latest source code: ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip
  632.  
  633.      Netscape's command line version of its JAR packager and signing tool is
  634.      called "zigbert". They also have a signing tool with GUI written in
  635.      Java. More info
  636.      http://developer.netscape.com/software/signedobj/jarpack.html
  637.  
  638.      If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar):
  639.        1. zip your files uncompressed (can use WinZip 6.2 up);
  640.                Unix command:
  641.  
  642.                zip -r0 classes.zip <directories>
  643.  
  644.        2. Make sure the main class has no parent directory inside the
  645.           archive, (in other words, don't build an archive with
  646.           foo/bar/myMain.class, unless your myMain is in a package called
  647.           foo.bar. Instead start it at myMain.class). Your packages must be
  648.           placed in the archive using their corresponding filesystem
  649.           pathnames.
  650.        3. Put the archive in the same directory as the .html page.
  651.        4. Put something like the following tag in the .html file:
  652.  
  653.           <APPLET CODEBASE="."
  654.                   ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip
  655.                   CODE="my_main_class.class"
  656.                   WIDTH=600 HEIGHT=250>
  657.               </APPLET>
  658.  
  659.  
  660.      From JDK 1.1 on, an example of the applet tag used with a jar file is
  661.  
  662.      <APPLET ARCHIVE=myfile.jar
  663.                      CODE=myapplet.class
  664.                      WIDTH=600 HEIGHT=250>
  665.              </APPLET>
  666.  
  667.  
  668.      These lines will use an applet called myapplet that can be found in the
  669.      jarfile myfile.jar. An example applet tag of a jar file used to hold
  670.      classes in packages is
  671.  
  672.      <APPLET ARCHIVE="myclasses.jar"
  673.                      CODE="linden.net.MyApplet.class"
  674.                      WIDTH=480
  675.                      HEIGHT=120>
  676.              </APPLET>
  677.  
  678.  
  679.      You can supply several jar filenames in a comma-separated list. Jar
  680.      files are in compressed PKZIP format.
  681.  
  682.   4. (Sect. 3) Can I compile a Java program to a binary executable, .exe on
  683.      a PC?
  684.  
  685.      [*] Compiling into native code destroys portability, which is one of
  686.      the main benefits of Java. If you want to create a native executable
  687.      because you wanted to make it easy to distribute and use programs,
  688.      consider a Jar file instead.
  689.      Some companies make products that do this. See the webpages for
  690.      Symantec http://www.symantec.com, Supercede http://www.supercede.com,
  691.      and Tower Technology http://www.twr.com. The first two are targeted to
  692.      Windows. Tower Technology supports several flavors of Unix.
  693.  
  694.      Also, there is a native Java compiler from IBM, known as the HPJ (High
  695.      Performance Java) compiler. One user has reported that it created a 2Mb
  696.      executable from a 12K java file, and did not run any faster. See
  697.      http://www.alphaworks.ibm.com/
  698.  
  699.      See also Instantiations JOVE http://www.instantiations.com/jove.htm,
  700.      the paper about the Toba project
  701.      http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf,
  702.      Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at
  703.      http://www.nwfusion.com/news/0209java.html
  704.  
  705.      Compiling to native code takes away the most significant benefit of
  706.      Java: portability of executables. Further, if you want your Java DLL
  707.      (or .exe) to interact with C++, you'll have to specify which specific
  708.      C++ compiler and/or actually compile some sort of linkage via the
  709.      appropriate C++ compiler. Because C++ does not have a standard ABI
  710.      there is a big problem with interoperability. Every C++ compiler uses a
  711.      different object model, a different way of laying out class members,
  712.      and a different way of "mangling" names for the linker.
  713.  
  714.      C is much simpler. The only question here is how structures are
  715.      "packed" (i.e., are integers aligned on four-byte bounds?). All the C++
  716.      compilers can interact with C code, thanks to 'extern "C"'
  717.      declarations.
  718.  
  719.      Consider carefully why you want to compile to a native executable, and
  720.      whether there is a Java way to accomplish your goal. There may be a
  721.      good reason for compiling to native code, but it needs to be thought
  722.      through.
  723.  
  724.   5. (Sect. 3) How can I performance profile my Java code?
  725.  
  726.      [*]java -prof MyClass
  727.  
  728.      produces some basic output in a file called java.prof, showing the
  729.      number of times methods were invoked. The output lines are of the form:
  730.           # of calls     method called      called by        time spent
  731.      On a Unix system, you can sort the file with something like
  732.  
  733.      sort -r +82 <java.prof > java.sort
  734.  
  735.      More and better Java tools are a third party opportunity. One Java
  736.      profiler is JProbe Profiler, available from http://www.klg.com/jprobe.
  737.      JProbe is said to be easy to use. Another profiler is OptimizeIt,
  738.      available from http://www.optimizeit.com. Each of these profilers has
  739.      performance tuning, which shows which methods took how much time, and
  740.      also memory tuning, which shows what objects are in memory and how they
  741.      were allocated. Both are important things to know. The latest version
  742.      of the CodeWarrior IDE http://www.metrowerks.com has a time-based
  743.      profiler for Java code. Java Workshop from Sun also has a time-based
  744.      profiler.
  745.  
  746.   6. (Sect. 3) When I use javadoc and I click on any java class included in
  747.      the JDK why do I get this message?
  748.  
  749.          Netscape is unable to find the file or directory named:
  750.          /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html
  751.  
  752.  
  753.      [*] References to the JDK classes assume that all generated html files
  754.      are in the same directory and, in fact, that all files for all classes
  755.      referenced are generated at the same time. There is no way to generate
  756.      files incrementally and have them all reference each other, as you
  757.      would like.
  758.  
  759.      As long as you have source for everything involved (including the JDK
  760.      and all third-party classes), you can list all of your packages and all
  761.      of the others on the javadoc command line and generate the whole set at
  762.      once, but it is burdensome. Of course, if you receive any libraries as
  763.      .class files, even this workaround will not suffice.
  764.  
  765.      Also javadoc will not generate the image files - you need to get them
  766.      from the images directory under the JDK API documentation files. You
  767.      can just copy the entire directory into your own doc directory. javadoc
  768.      is a very nice concept, with a few implementation flaws.
  769.  
  770.      Polardoc http://www.ualberta.ca/~tgee/polardoc can be used to
  771.      workaround some JavaDoc limitations.
  772.  
  773.   7. (Sect. 3) I'm working on a project with lots of classes and I use the
  774.      JDK. A recompile from scratch takes forever when I do it a class at a
  775.      time. How do I recompile everything?
  776.  
  777.      [*] The first way is
  778.           javac *.java
  779.  
  780.      Another way is
  781.           javac -depend tip.java
  782.  
  783.      where "tip.java" is a class "at the tip of the iceberg", i.e. that
  784.      depends on (uses) all the other classes. Typically, this may be your
  785.      main class. However, "-depend" is known to be buggy and cannot be
  786.      relied upon. It also doesn't issue compile commands in parallel to make
  787.      use of multi-processor systems.
  788.  
  789.      Without the "-depend" option, the standard "javac files" doesn't look
  790.      beyond the immediately adjacent dependencies to find classes lower down
  791.      the hierarchy where the source has changed.
  792.  
  793.      The -depend options searches recursively for depending classes and
  794.      recompiles it. This option doesn't help when you have dynamically
  795.      loaded classes whose names cannot be determined by the compiler from
  796.      the dependency graph. E.g. you use something like
  797.           Class.forName(argv[0]);
  798.  
  799.      The author of the code using those classes should make sure that those
  800.      classes are mentioned in a Makefile.
  801.  
  802.   8. (Sect. 3) Why do I get the java.lang.UnsatisfiedLinkError when I run my
  803.      Java program containing Native Method invocations?
  804.  
  805.      [*] Your program is not able to find your shared library or DLL.
  806.  
  807.      On Windows 95/NT, make sure that the DLL exists in a path that is
  808.      included within the PATH environment variable. (This need is true for
  809.      both standard (untrusted) applications and trusted applets. At least,
  810.      if you use the Java Plug-in to give yourself standard Java inside a
  811.      browser).
  812.  
  813.      On Solaris, make sure that the environment variable LD_LIBRARY_PATH
  814.      includes the path of your shared library.
  815.  
  816.   9. (Sect. 3) An anonymous class can't seem to access a private outer
  817.      method. Why is that?
  818.  
  819.      [*] It's a known bug in the JDK 1.1.4. The code is:
  820.  
  821.          public class MyDialog {
  822.  
  823.                  void Setup() {
  824.                  addWindowListener( new WindowAdapter() {
  825.                        public void windowClosing(WindowEvent e) {
  826.                               myCloseWindow(); }
  827.                        }
  828.                        );     // anon inner class
  829.                  }
  830.  
  831.              private void myCloseWindow() {   // private outer method
  832.                  dispose();
  833.              }
  834.          }
  835.  
  836.      This code sends javac into an infinite loop. The workaround is to make
  837.      the private method non-private, or to make the inner class a named
  838.      class. Sun put a workaround in the compiler to silently set the field
  839.      to package access.
  840.  
  841.  10. (Sect. 3) What are the major Java releases and their contents?
  842.  
  843.      [*] There have been three Java releases from Sun so far, plus a number
  844.      of bugfix (dot-dot) releases. The releases are:
  845.         o JDK 1.0.2
  846.           This was the release FCS in May 1996. It had some security fixes
  847.           over JDK 1.0.
  848.         o JDK 1.1
  849.           This release (Feb 1997) introduced a new event model in the window
  850.           system. It also made JDBC support and beans support a standard
  851.           feature. It changed and standardized the native code interface to
  852.           JNI. It also introduced inner classes.
  853.         o JDK 1.2
  854.           This release (due November 1998) made the Swing library a standard
  855.           feature. Swing is a set of rich platform-independent graphical
  856.           components.
  857.  
  858.  11. (Sect. 3) What is the difference between jre and java?
  859.  
  860.      [*] They are functionally equivalent, with minor differences in the
  861.      handling of default classpath and options supported. To reduce
  862.      confusion, the jre command will go away in JDK 1.2. (Instead there will
  863.      be a "java" command in both bin and jre/bin. The classes.zip file will
  864.      broken into 3 jar files: It changed and standardized the native code
  865.      interface to JNI. It also
  866.  
  867.      jre.exe is the runtime stub that comes with the Java Runtime
  868.      Environment (it's also in the JDK). It ignores the CLASSPATH
  869.      environment setting in favor of its own internally generated default
  870.      and whatever is supplied on the cmd line using -cp or -classpath. It's
  871.      intended to be a bit simpler for those who are only ever running Java
  872.      programs, not developing them.
  873.  
  874.      java.exe is the runtime stub that only comes with the JDK. It uses the
  875.      CLASSPATH environment setting as a starting point and then tacks on its
  876.      own internally generated entries.
  877.  
  878.      They both serve the same purpose and that's to start a Java VM, have it
  879.      run a Java application, then terminate. The source for jre.exe is
  880.      provided in the JDK. The source to java.exe is provided only in the JDK
  881.      Source distribution.
  882.  
  883.  12. (Sect. 3) What IDEs (Integrated Development Environments) are there?
  884.  
  885.      [*] Some popular IDEs include:
  886.  
  887.       Apptivity 2.0 (Progress) http://www.apptivity.com
  888.       CodeWarrior Professional http://www.metrowerks.com
  889.       GRASP (product is free)  http://www.eng.auburn.edu/grasp
  890.       Grinder                  http://www.tpex.com
  891.       Java WorkShop 2.0 (Sun)  http://www.sun.com/workshop/java
  892.       Javelin, Visual Object
  893.       Development for Java     http://www.stepahead.com.au
  894.       JBuilder (Borland)       http://www.borland.com/jbuilder
  895.       JDE for emacs            http://sunsite.auc.dk/jde/
  896.       Kawa (Webcetera)         http://www.tek-tools.com/kawa
  897.       NetBeans (Swing-based)   http://www.netbeans.com
  898.       PARTS alpha (ObjectShare)http://www.objectshare.com
  899.       PowerJ ? (Sybase)        http://www.sybase.com/products/powerj
  900.       SilverStream             http://www.silverstream.com
  901.       Super Mojo (Penumbra)    http://www.penumbrasoftware.com
  902.       SuperCede 2.0 (Asymetrix)http://www.supercede.com
  903.       teikade 1.8R2 (PFU Ltd)  http://www.pfu.co.jp/teikade
  904.       Together/J 2.0 (Object
  905.       Intl Inc.)               http://www.oi.com
  906.       Visaj 1.0.1 (Imperial SW
  907.       Tech)                    http://www.imperial-software-tech.co.uk
  908.       VisualAge 1.0 (IBM)      http://www.software.ibm.com/ad/vajava
  909.       Visual Cafe 2.1
  910.       (Symantec)               http://cafe.symantec.com
  911.       Visual J++ (Microsoft)   (deliberately incompatible; not recommended)
  912.       Xelfi 0.94               http://www.xelfi.com
  913.  
  914.  13. (Sect. 3) Why is Visual J++ not recommended?
  915.  
  916.      Because Microsoft's strategic objective is "Kill cross-platform Java"
  917.  
  918.      [*] It is not in Microsoft's financial interest to allow users to
  919.      easily move software to different platforms. Microsoft is the only
  920.      company in the computer industry that is actively trying to undermine
  921.      Java. This is not speculation -- the Department of Justice's lawsuit
  922.      quoted a Microsoft memo describing the strategic objective to "kill
  923.      cross-platform Java by grow[ing] the polluted Java market". See
  924.      http://www.usdoj.gov/atr/cases/f1700/1762.htm
  925.  
  926.      Microsoft is being sued because of unauthorized changes it made in
  927.      Java. A federal judge issued a preliminary injunction against Microsoft
  928.      in March 1998, prohibiting them from labelling their incompatible J++
  929.      product as Java.
  930.  
  931.      Speak to your management
  932.      chain - how comfortable do
  933.      they feel using a Microsoft product that is embroiled in a legal
  934.      dispute, that introduces deliberate incompatibilities, and whose stated
  935.      goal is to lock you in to one platform? It is a safer choice to get
  936.      standard Java from any other source than Microsoft. You can use these
  937.      facts to move your company to standard Java.
  938.  
  939.      The best way for programmers to support portable Java is to reject
  940.      "polluted" non-standard tools from the only company pushing them:
  941.      Microsoft. As a Java programmer please join the Java Lobby, an
  942.      independent organization dedicated to representing non-vendor interests
  943.      in Java. It's free, and you can sign up by visiting
  944.      http://www.javalobby.org for details. Other ways to encourage portable
  945.      java:
  946.         o Use development environments from other vendors, or convert
  947.           Microsoft Visual J++ to use Sun's JDK, following the instructions
  948.           at http://www.orbiter.demon.co.uk/
  949.         o Use Netscape Communicator (not Internet Explorer)
  950.         o If required to use Internet Explorer, use the Java Plug-In to get
  951.           a standard Java system inside it.
  952.         o Use a JVM from GNU, Kaffe, or Sun (not Microsoft's J++ SDK)
  953.  
  954.         o Free standard Java compilers and the Java Plug-In can be
  955.           downloaded from http://java.sun.com.
  956.         o Free standard Java Virtual Machines can be downloaded from
  957.           http://www.kaffe.org, http://www.oryxsoft.com/projects/gvm, and
  958.           http://www.redhat.com/linux-info/jolt
  959.         o Free Java AWT software can be downloaded from
  960.           http://www.biss-net.com/biss-awt.html and the files are all at
  961.           ftp.java-linux.org (the linux site) too.
  962.         o Free Java software can be downloaded from
  963.           http://www.gnu.org/software/java/java.html
  964.  
  965.      Just for the record, the May 1998 federal case against Microsoft has
  966.      nothing to do with innovation, or product design. Microsoft is charged
  967.      with
  968.         o taking anti-competitive action to exclude competition in browsers,
  969.           in order to protect its monopoly in desktop operating systems.
  970.         o using its monopoly to impose restrictive agreements that require
  971.           PC manufacturers to accept the Microsoft browser with Windows, and
  972.           that hinder the promotion of competing browsers.
  973.      Many people think that contracts prohibiting the distribution of a
  974.      third party's products are somewhat sleazy. Such contracts are also in
  975.      restraint of competition and illegal when used by a monopoly. This is
  976.      why Microsoft is facing mounting legal problems in the United States,
  977.      Japan, Brazil, and the European Union.
  978.  
  979.                        -------------------------------
  980.  
  981. 4. Getting Started
  982.  
  983.      Don't forget to look at the "Compiler Messages" in the next section,
  984.      too.
  985.  
  986.   1. (Sect. 4) What is the easiest way to get started with Java?
  987.  
  988.      [*] Follow these steps.
  989.        1. Download a free Java compiler from http://java.sun.com
  990.        2. Read the free Java tutorial, at the same website (bookmark it, so
  991.           you will easily find it again).
  992.        3. Avoid Microsoft's J++ product, which is in the words of
  993.           Microsoft's own employees "polluted Java".
  994.        4. Look at the beginning of this FAQ for book info and book reviews.
  995.           There is no one perfect Java book. The right book depends on the
  996.           style and pace that you are most comfortable with. Amazon.com has
  997.           good info and reviews on Java books.
  998.        5. Search this FAQ when something in Java confuses you. Many people
  999.           have trodden this path before you, and the FAQ contains the
  1000.           accumulated knowledge and pointers to other references.
  1001.   2. (Sect. 4) Why doesn't my "Hello World!" program compile?
  1002.  
  1003.      [*] There are three basic possibilities:
  1004.        1. Are you successfully running the javac compiler?
  1005.           Try
  1006.  
  1007.           javac -garbage
  1008.  
  1009.           to see if it prints out a message about correct usage. If not,
  1010.           invoke javac using the full pathname, or set your PATH variable to
  1011.           include the directory that contains javac.
  1012.        2. Is the CLASSPATH environment variable used correctly?
  1013.           In JDK 1.0.2, it was a mistake for beginners not to set CLASSPATH.
  1014.  
  1015.           In JDK 1.1, it is a mistake when beginners do set CLASSPATH.
  1016.           When CLASSPATH is wrong, javac will tell you it can't find
  1017.           definitions for classes you reference in the source file. For
  1018.           information on setting up the CLASSPATH, see Question 4.3
  1019.        3. Is the source correct?
  1020.           Here javac will emit error and warning messages. See the questions
  1021.           on compiler messages in the next section.
  1022.  
  1023.   3. (Sect. 4) Why doesn't my "Hello World!" program run?
  1024.  
  1025.      [*] There are five common mistakes that cause your VM (java or browser)
  1026.      to be unable to execute your classes
  1027.        1. First, did you write an applet or an application? If an applet,
  1028.           you must make sure that you did extend the java.applet.Applet
  1029.           class.
  1030.        2. You must declare your main class as "public". If you don't,
  1031.           unfortunately some systems will still run the code, while others
  1032.           won't. The main class is either the one with the main() method in,
  1033.           or in the case of an Applet, the class that extends Applet.
  1034.        3. Your class name and the file name must match exactly, even letter
  1035.           case. If your class is HelloWorld, your source file must be
  1036.           HelloWorld.java and your class file will be "HelloWorld.class".
  1037.        4. If an Applet, and you used ftp to transfer the classes to the
  1038.           server, you must ftp all the classes, and you must use BINARY
  1039.           transfer not ASCII.
  1040.        5. Errors in setting the CLASSPATH (and/or codebase in an applet).
  1041.           Even seasoned programmers do this, pointing inside a package or
  1042.           mistyping a path delimiter. For information on setting up the
  1043.           CLASSPATH and codebase, see Question 4.3
  1044.  
  1045.      If you are running an applet, you should check the following further
  1046.      points:
  1047.        1. If your class isn't loading, recheck the HTML applet tag.
  1048.        2. If you are writing to System.out, the results are displayed in the
  1049.           browser's java console. You'll have to create a window if you want
  1050.           one.
  1051.        3. Make sure your browser is compatible with the Java language
  1052.           features you are using. Internet Explorer and older versions of
  1053.           Netscape's browsers have omitted some support for JDK 1.1. Try
  1054.           your applet in the JDK's appletviewer first.
  1055.  
  1056.   4. How do I set the CLASSPATH?
  1057.  
  1058.      [*] The CLASSPATH environment variable tells the VM's class loader
  1059.      where to find classes that are directly or indirectly invoked,
  1060.      including system classes. The CLASSPATH variable should
  1061.         o point to the class directory, for classes not in a package.
  1062.         o point to the package root, for classes in a package. The root is
  1063.           the parent directory of the highest directory of the package name.
  1064.         o point directly to the zip or jar file, if the classes are in an
  1065.           archive file. You may have to list the contents of the archive to
  1066.           get the correct package/path name for the class.
  1067.           Separate multiple paths and archives with a platform-specific
  1068.           separator, ";" for Windows; ":" for Solaris
  1069.      Also remember that
  1070.         o Browsers set the CLASSPATH to the directory of the HTML file, plus
  1071.           the codebase parameter.
  1072.         o in JDK 1.1 and after, java adds the system classes
  1073.           (lib/classes.zip), so you don't have to.
  1074.         o most versions of java add "." (current directory), so you don't
  1075.           have to. (But jre doesn't - see below.)
  1076.         o JDK 1.1 jre tool does not use the CLASSPATH variable or assume the
  1077.           current directory. (On Solaris, CLASSPATH does work.)
  1078.  
  1079.      From JDK 1.1.2 on, it is generally an error if the user sets the
  1080.      CLASSPATH to include classes.zip. But CLASSPATH will need to be set to
  1081.         o point to the roots of the programmer's own packages, and third
  1082.           party packages
  1083.         o use rmic
  1084.         o use unbundled packages like Swing in JDK 1.1
  1085.         o point to native code libraries.
  1086.  
  1087.      If you're not doing any of these, do not set CLASSPATH. If you have set
  1088.      it, unset it.
  1089.      Below you'll find examples for Windows (basic application class),
  1090.      Solaris (package class), javac (multiple packages), and browsers
  1091.      (applet codebase).
  1092.      -----------------------------
  1093.  
  1094.      Here's some Windows examples, assuming the application class is
  1095.  
  1096.      D:\src\tries\HelloWorld.class
  1097.  
  1098.              ## JDK 1.1,  no CLASSPATH set
  1099.              > cd D:\src\tries\
  1100.              > D:\jdk11\bin\java HelloWorld
  1101.                # OK: 1.1 implicitly adds classes.zip and current dir
  1102.  
  1103.              > D:\jdk11\bin\jre HelloWorld
  1104.                # FAILS: jre does not automatically add . to CLASSPATH
  1105.  
  1106.              > cd D:\
  1107.              > D:\jdk11\bin\jre -cp D:\src\tries HelloWorld
  1108.                # OK: jre adds classes.zip, -cp adds class directory
  1109.  
  1110.              ## JDK 1.1,  CLASSPATH set
  1111.              > set CLASSPATH=D:\src\tries
  1112.              > D:\jdk11\bin\java HelloWorld
  1113.                # OK: java using CLASSPATH
  1114.  
  1115.              > D:\jdk11\bin\jre HelloWorld
  1116.                # FAILS: jre does not use CLASSPATH (on Windows)
  1117.  
  1118.              ## JDK 1.0.2,  CLASSPATH set
  1119.              > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
  1120.              > D:\jdk102\bin\java HelloWorld
  1121.                # OK:
  1122.  
  1123.              > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
  1124.              > D:\jdk11\bin\java HelloWorld
  1125.                # FAILS: exception in thread NULL - wrong system classes
  1126.  
  1127.  
  1128.      -----------------------------
  1129.  
  1130.      Here's some Solaris examples, assuming the application class is
  1131.  
  1132.      /usr/src/com/devjoes/killer/App.class
  1133.  
  1134.      and it is in package com.devjoes.killer:
  1135.  
  1136.              # JDK 1.1, no CLASSPATH set
  1137.              $ /usr/bin/jdk11/bin/jre  -cp /usr/src   com.devjoes.killer.App
  1138.                # OK:
  1139.  
  1140.              $ cd /usr/src/com/devjoes/killer/
  1141.              $ /usr/bin/jdk11/bin/java App
  1142.                # fails: class name and path are wrong
  1143.  
  1144.              $ CLASSPATH=/usr/src/
  1145.              $ /usr/bin/jdk11/bin/java App
  1146.                # fails: class name is com.devjoes.killer.App
  1147.  
  1148.              $ /usr/bin/jdk11/bin/java com.devjoes.killer.App
  1149.                # OK:
  1150.  
  1151.  
  1152.      -----------------------------
  1153.  
  1154.      Here's some javac examples, for both Solaris and Windows, based on the
  1155.      following:
  1156.       Source files                package           Makes the call
  1157.       /usr/src/pack/Minimal.java  package pack      pack.sub.Try.run()
  1158.       /usr/src/pack/sub/Try.java  package pack.sub  (nothing)
  1159.  
  1160.              $ CLASSPATH=""
  1161.              $ /usr/bin/jdk11/bin/javac /usr/src/pack/sub/Try.java
  1162.                # OK: works fine
  1163.  
  1164.              $ /usr/bin/jdk11/bin/javac /usr/src/pack/Minimal.java
  1165.                # FAILS: can't find pack.sub.Try
  1166.  
  1167.              $ cd /usr/src
  1168.              $ /usr/bin/jdk10/bin/javac pack/Minimal.java
  1169.                # OK: finds pack.sub.Try based on . as package root
  1170.  
  1171.              $ cd /usr/src/pack
  1172.              $ CLASSPATH=/usr/src
  1173.              $ /usr/bin/jdk11/bin/javac Minimal.java
  1174.                # OK: finds pack.sub.Try based on CLASSPATH
  1175.  
  1176.  
  1177.      Now assume the killer application class
  1178.  
  1179.      /usr/src/com/devjoes/killer/FastApp.java
  1180.  
  1181.      (in package com.devjoes.killer) uses a third-party package in a jar
  1182.      file
  1183.  
  1184.      /usr/jars/JShapes.jar
  1185.  
  1186.      but makes no other reference to other classes. The following works
  1187.      fine:
  1188.  
  1189.              $ CLASSPATH=/usr/jars/JShapes.jar
  1190.              $ cd /usr/src/com/devjoes
  1191.              $ /usr/bin/jdk11/bin/javac killer/FastApp.java
  1192.  
  1193.  
  1194.      Finally, some applet examples. Many applets only use one class, in the
  1195.      same directory as the html file:
  1196.  
  1197.      <applet code=ArcTest.class height=400 width=400>
  1198.  
  1199.  
  1200.      To use classes in subdirectory, use the codebase parameter:
  1201.  
  1202.      <applet codebase="mysubdir/" code=ArcTest.class ..
  1203.  
  1204.  
  1205.      To use classes in an archive, use the archive parameter:
  1206.  
  1207.      <applet archive="applets.jar" code=ArcTest.class ..
  1208.  
  1209.  
  1210.      See also: JDK 1.1 ReadMe
  1211.      Solaris JDK 1.1 tool documentation
  1212.      Win32 JDK 1.1 tool documentation
  1213.  
  1214.   5. (Sect. 4) How do I do keyboard (interactive) I/O in Java?
  1215.  
  1216.      [*] Interactive I/O in Java is very poorly supported. Programmers must
  1217.      piece together several library classes in non-obvious ways to get the
  1218.      required functionality. See the answer to Question 6.1.
  1219.  
  1220.   6. (Sect. 4) How do I do file I/O in an applet?
  1221.  
  1222.      [*] By default, an applet can read files on the server, but not write
  1223.      them, and has no access to the client. This is for reasons of security.
  1224.      It would be very unsafe to let any old applet that you downloaded from
  1225.      an unknown origin on the Internet read/write your files. It would be as
  1226.      unwise as allowing this kind of access to an ActiveX control (which is
  1227.      one reason ActiveX is dead on the Internet).
  1228.  
  1229.      There are several different ways to relax the default rules. See the
  1230.      answer to Question 7.8.
  1231.  
  1232.   7. (Sect. 4) How do I do I/O to the serial port on my computer?
  1233.  
  1234.      [*] Java 1.0 and 1.1 do not have a serial port API. There are several
  1235.      commercially-available libraries that supply the needed functionality.
  1236.      JDK 1.2 introduces access to the serial and parallel ports as an
  1237.      extension (optional extra) library. See also the answer to Question
  1238.      6.3.
  1239.  
  1240.   8. (Sect. 4) How do I do formatted I/O like printf and scanf in C/C++?
  1241.  
  1242.      [*] The java.text package introduced with Java 1.1 supports formatted
  1243.      I/O. See also the answer to questions 7.11, 7.12, and 16.7.
  1244.  
  1245.   9. (Sect. 4) I have spent more debugging time finding case (upper vs
  1246.      lower) typos than everything else put together and squared!
  1247.  
  1248.      [*] Do not forget that your remark must be phrased in the form of a
  1249.      question to win on FAQ Jeopardy. In any event, it is worth reminding
  1250.      those new to Java that letter case really matters in Java, and that the
  1251.      names of public classes should exactly match (including case) the names
  1252.      of the files they live in. See also the answer to Question 4.1.2
  1253.  
  1254.  10. (Sect. 4) Why do I get this compiler error: "Can't make static
  1255.      reference to method..."?
  1256.  
  1257.      [*] Your code probably looks something like this:
  1258.  
  1259.      class myclass {
  1260.                  public static void main(String args[]) {
  1261.                      myMethod();
  1262.                  }
  1263.  
  1264.                  public void myMethod() {
  1265.                      //some code
  1266.                  }
  1267.              }
  1268.  
  1269.  
  1270.      The issue is this: a static method means it belongs to the class, not
  1271.      each individual object. If you leave the static keyword off (the usual
  1272.      case) as is done here with the method "myMethod()", it means that
  1273.      method can only be invoked on an object. But your call from main() has
  1274.      not told myMethod() which object it is to be invoked on. Inside a
  1275.      non-static method, you don't have to provide this information, as it
  1276.      assumes you mean the same object on which it was invoked. But when
  1277.      calling from a static method, you must provide the information, and you
  1278.      haven't - hence the error message.
  1279.  
  1280.      A common fix is to instantiate a member of the class, on which to
  1281.      invoke myMethod(), like this:
  1282.  
  1283.              public static void main(String args[]) {
  1284.                  myclass m = new myclass();
  1285.                  m.myMethod();
  1286.              }
  1287.  
  1288.  
  1289.      This problem is especially common when you are writing code that you
  1290.      want to run as an applet and as an application. Naturally, you call
  1291.      init() and start() from main. What you really need to do is:
  1292.  
  1293.              public static void main(String[] args) {
  1294.                  Applet ma = new myApplet();
  1295.                  ma.init();
  1296.                  ma.start();
  1297.              }
  1298.  
  1299.  
  1300.  11. (Sect. 4) Why can't I do myArray.length() ? Arrays are just objects,
  1301.      right?
  1302.  
  1303.      [*] Yes, the Java specification says that arrays are object references
  1304.      [JLS 10.2] just like classes are. However, arrays cannot contain
  1305.      methods. Instead you have to use myArray.length, which is a data item
  1306.      (not a method) called "length", belonging to myArray.
  1307.  
  1308.  12. (Sect. 4) How do I close a Java window by using the icon in the upper
  1309.      right hand corner of a window?
  1310.  
  1311.      [*] Create an event handler class to extend WindowAdapter. Then
  1312.      override WindowAdapter's windowClosing() to do the actions you want
  1313.      when a window's "close" action is clicked. Then add that to the
  1314.      listeners for that window.
  1315.  
  1316.      import java.awt.*;
  1317.      import java.awt.event.*;
  1318.  
  1319.      public class MyFrame extends Frame {
  1320.          public MyFrame(String s) {super(s);}
  1321.  
  1322.          public class WL extends WindowAdapter {
  1323.              public void windowClosing(WindowEvent e) {System.exit(0);}
  1324.          }
  1325.  
  1326.          // do your other Frame stuff
  1327.  
  1328.      }
  1329.  
  1330.  
  1331.      Somewhere in your initialization code, put:
  1332.  
  1333.              f1.addWindowListener( f1. new WL()  );
  1334.  
  1335.  
  1336.      This last syntax is not commonly known to many people yet, it's another
  1337.      wacky artifact of inner classes.
  1338.  
  1339.      Alternatively, combining the inner class and setting the handler in one
  1340.      go, you could do this:
  1341.  
  1342.              MyFrame f1 = new f("wave");
  1343.  
  1344.              f1.addWindowListener( new WindowAdapter() {
  1345.                  public void windowClosing(WindowEvent e) {
  1346.                      // and/or setVisible(false) and/or dispose()
  1347.                      System.exit(0); }
  1348.              });
  1349.  
  1350.  
  1351.      See also the answer to questions 4.0.19, 4.0.30 and 15.7.
  1352.  
  1353.  13. (Sect. 4) Why is b+=100; OK, but b = b+100; fails to compile?
  1354.  
  1355.      [*] You have code like this
  1356.  
  1357.        byte b = 0;
  1358.        Incompatible type for =. Explicit cast needed to convert int to byte.
  1359.        b = b + 100;    // compiler error message
  1360.          ^
  1361.        b += 100;       // works OK
  1362.  
  1363.      The reason is "promotion". Arithmetic expressions are promoted to the
  1364.      type of the longest, floatiest operand in them, or at least to int. The
  1365.      first statement involves the assignment of an expression. The
  1366.      expression is promoted to 32 bits, and must be cast back down to 8
  1367.      bits, like this "b = (byte) (b+100);". The second is an operator
  1368.      assignment, and the cast back to byte takes place automatically. The
  1369.      Java Specification says:
  1370.           "A compound assignment expression of the form E1 op= E2 is
  1371.           equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is
  1372.           the type of E1, except that E1 is evaluated only once" [JLS
  1373.           15.25.2]
  1374.  
  1375.      The compile-time narrowing of constants means that code such as:
  1376.  
  1377.      byte theAnswer = 42;
  1378.  
  1379.      is allowed, with no cast necessary. [JLS 5.2]
  1380.  
  1381.  14. (Sect. 4) How do I add two Float objects together?
  1382.  
  1383.      [*] You want to write code like this
  1384.  
  1385.              Float One;
  1386.              Float Two;
  1387.              Float Hard = One + Two;
  1388.  
  1389.  
  1390.      but the compiler does not allow it.
  1391.  
  1392.      Java has two separate ways of representing a 32 bit floating point
  1393.      number, Float and float. Float is a class, that whose sole purpose is
  1394.      to "wrap" a floating point number so it can be treated as an object.
  1395.      The class does not support floating point arithmetic, because the
  1396.      performance would be too slow. float is a primitive type (like int)
  1397.      that is used for floating point arithmetic.
  1398.  
  1399.      You choose one or the other depending on your predominant use. If all
  1400.      you need of your floating point numbers is arithmetic, declare them to
  1401.      be "float". If you need to use them as objects, for example to place
  1402.      them in a Vector, declare them as "Float".
  1403.  
  1404.      If you need both, tough. You have to declare them one way and convert
  1405.      whenever you need the capabilities of the other. Your specific code can
  1406.      be written as:
  1407.  
  1408.              Float One = new Float(1.0);
  1409.              Float Two = new Float(2.0);
  1410.              Float Hard = new Float(One.floatValue() + Two.floatValue());
  1411.  
  1412.  
  1413.      See also questions 3.8 , 5.1, and 10.1.
  1414.  
  1415.  15. (Sect. 4) How can I put all my classes and resources into one file and
  1416.      have java run it?
  1417.  
  1418.      [*] Use a JAR file. Put all the files in a JAR, then use the jre to run
  1419.      the app, like:
  1420.  
  1421.              jre -cp app.jar Main
  1422.  
  1423.  
  1424.      assuming the jar is called app.jar and it has a class called Main that
  1425.      has the main() method for the application.
  1426.  
  1427.  16. (Sect. 4) How can I see line numbers in a stack trace using JDK 1.1.6?
  1428.  
  1429.      [*] After switching from JDK 1.1.5 to JDK 1.1.6, the stack trace of
  1430.      uncaught exception no longer has source code line numbers. It only says
  1431.      <Compiled Code>.
  1432.  
  1433.      To see the line numbers where your program throws an exception, use the
  1434.      -nojit option to turn off the Just In Time compiling. One correspondent
  1435.      suggests that this is only in jre, not java.
  1436.  
  1437.      Another correspondent says that the environment variable JAVA_COMPCMD
  1438.      can be set to the following values:
  1439.      FORCE_SIGNON - shows JIT version
  1440.      DISABLE - disable the JIT
  1441.      STACKTRACE - shows "some" line numbers
  1442.  
  1443.                           -----------------------------
  1444.  
  1445.      Windows-Specific
  1446.  
  1447.  17. Is there a Java implementation for Windows 3.1?
  1448.  
  1449.      [*] Yes. See Question 1.6 It's not that great though because Windows
  1450.      3.1 has inadequate features to support great software.
  1451.  
  1452.  18. (Sect. 4) I'm using Win95, and my DOS window won't accept filenames
  1453.      longer than 8.3.
  1454.      "This program cannot be run in DOS mode"
  1455.  
  1456.      [*] Both these problems are resolved by the same process. Assuming
  1457.      you're running the Win95/98 command.com, then you've changed the MS-DOS
  1458.      Prompt options under the "Properties" menu item. In the Properties
  1459.      dialog, Program->Advanced gets you a dialog. Here, make sure the
  1460.      "Prevent MS-DOS-based programs from detecting Windows" checkbox is
  1461.  
  1462.      If the option is checked you get exactly the kind of behavior you're
  1463.      seeing. The option is unchecked by default, so it must have been
  1464.      selected at some time in the past. Change it back to unchecked.
  1465.  
  1466.  19. (Sect. 4) I'm using Notepad to edit my files, and how can I save them
  1467.      with the extension ".java"? Also, in notepad some source files have all
  1468.      the characters on one line. Why is that?
  1469.  
  1470.      [*] First answer: put the entire filename in quotes in the save dialog.
  1471.      Once you have created your first Java file, double click on it in
  1472.      Explorer, select "Notepad" from the "Open with" box, and Notepad will
  1473.      stop adding the spurious ".txt" to your .java files.
  1474.  
  1475.      Second answer: Notepad expects to see a "carriage return/line feed"
  1476.      pair at the end of each line, rather than just the "newline"
  1477.      (line-feed) commonly used on Unix. Use this program to expand all
  1478.      newlines,
  1479.  
  1480.      /*
  1481.       * Usage: jre crlf file1.java file2.java ... fileN.java
  1482.        */
  1483.  
  1484.      import java.io.*;
  1485.      class crlf {
  1486.          public static void main(String s[]){
  1487.              byte b[]; byte p;
  1488.              FileInputStream is;
  1489.              BufferedOutputStream os;
  1490.              File f;
  1491.              for (int i=0; i < s.length;i++){
  1492.                  try{
  1493.                      f=new File(s[i]);
  1494.                      b=new byte[(int)f.length()];
  1495.                      is = new FileInputStream(f);
  1496.                      is.read(b); is.close();
  1497.                      os = new BufferedOutputStream(
  1498.                      new FileOutputStream(s[i]),b.length);
  1499.                      p='?';
  1500.                      for(int j=0; j < b.length; j++){
  1501.                          if((p!='\r')&&(b[j]=='\n')) os.write('\r');
  1502.                          p=b[j]; os.write(p);
  1503.                      }
  1504.                      os.flush(); os.close();
  1505.                  }catch(IOException e){
  1506.                      System.err.println(e.toString());
  1507.                  }
  1508.              }
  1509.          }
  1510.      }
  1511.  
  1512.  
  1513.      The source code is to show new users a way to make a simple program
  1514.      which can read a file and write it out buffered.
  1515.  
  1516.      Compile with "javac crlf.java" and run with
  1517.      java crlf outfile.txt
  1518.      or just use Wordpad instead of Notepad. Wordpad is under
  1519.      Start->Programs->Accessories->WordPad
  1520.  
  1521.  20. (Sect. 4) What's J++6?
  1522.  
  1523.      [*] It is an abbreviation for "Microsoft J++ version 6". Microsoft
  1524.      launched J++ 1.0 in 1996 and it was compatible with Java 1.0. When Java
  1525.      1.1 came out, Microsoft decided not to support key parts of it, such as
  1526.      JNI, JFC, RMI, and Java Beans. Nevertheless, Microsoft moved the
  1527.      version number of J++ to 1.1, which confused people who expected it to
  1528.      support JDK 1.1
  1529.  
  1530.      Microsoft has continued its attempt to fragment and undermine support
  1531.      for Java with J++6. First, it bumped the version number up, skipping
  1532.      over releases 1.2 , 3, 4, and 5. This aligned the number with other MS
  1533.      products, but falsely conveys the impression that J++6 is an equally
  1534.      stable and mature product. (A similar thing ocurred with NT, which was
  1535.      introduced at version 3.1, not version 1.0). Then Microsoft introduced
  1536.      two new keywords ("delegate" and "multicast"), as well as the
  1537.      complexity of conditional compilation and conditional methods.
  1538.  
  1539.      Microsoft's SDK has been moved further and further from standard Java
  1540.      with each successive release. J++ combined with the visual editor
  1541.      generates calls to the Windows-only WFC library. Anyone writing Java
  1542.      code that uses VJ++6 is needlessly restricting their programs to only
  1543.      ever run on Microsoft platforms. Microsoft has been cut off from future
  1544.      Java technology, so they do not have JNI, JFC, RMI, Java Beans,
  1545.      IIOP/CORBA hooks, Swing, PLAF & Accessibility, the Security API, Drag N
  1546.      Drop, among other features. If you like Java, you should encourage
  1547.      Microsoft to be compatible by not using their divergent tools.
  1548.  
  1549.      The entire purpose of VJ++ is to get people producing near-Java code
  1550.      that only runs on Windows. The strategy is being challenged in the law
  1551.      courts, giving VJ++ an uncertain future. So please use one of the other
  1552.      free or inexpensive standard IDEs for Windows instead. See a list of
  1553.      IDEs in this FAQ.
  1554.  
  1555.      You may see some programmers refer to J--. By this they mean
  1556.      Microsoft's incompatible J++ SDK.
  1557.  
  1558.  21. (Sect. 4) How do I fix the message about "out of environment variable
  1559.      space"?
  1560.  
  1561.      [*] This occurs under Windows when you have long CLASSPATH names. You
  1562.      need to increase the enviroment space. Put this in your config.sys:
  1563.  
  1564.              shell=command /e:4096
  1565.  
  1566.  
  1567.                        -------------------------------
  1568.  
  1569. 5. Compiler Messages
  1570.  
  1571.      Most of the "questions" in this section are diagnostic messages from
  1572.      the compiler. Each answer explains what the message means, and how to
  1573.      avoid it.
  1574.  
  1575.   1. (Sect. 5) Why did I get an OutOfMemory error when porting working code
  1576.      from JDK 1.0.2 to 1.1?
  1577.  
  1578.      [*] The preset memory limit has changed. It went down to 16MB so as not
  1579.      to penalize low memory machines. You can adjust it with
  1580.  
  1581.      java -mx32m Frotz
  1582.  
  1583.      to get a 32MB extent.
  1584.  
  1585.      Also see the Runtime methods freeMemory() and totalMemory().
  1586.  
  1587.   2. (Sect. 5) Why do I get a "Statement not reached" error from javac for
  1588.      no apparent reason?
  1589.  
  1590.      [*] JDK 1.0 has a limit of 63 words of storage for local variables in
  1591.      any method. longs and doubles require two words of storage, and all
  1592.      other primitive types and all reference types require one word. If you
  1593.      assign values to more than 63 words of local variables, you will get a
  1594.      "Statement not reached" error on the statement after you assign to the
  1595.      variable that contains the 64th word. In JDK 1.1, the low limit was
  1596.      removed.
  1597.  
  1598.   3. (Sect. 5) class MyOrdinaryClass must be declared abstract.
  1599.      It does not define void actionPerformed(java.awt.event.ActionEvent)
  1600.  
  1601.      [*] This is one of those error messages where the compiler tries to
  1602.      guess what you meant, and gives you a message based on a wrong guess!
  1603.      So the message is confusing.
  1604.  
  1605.      Your MyOrdinaryClass class implements ActionListener, which means you
  1606.      must include a definition of the methods from the ActionListener
  1607.      interface.
  1608.  
  1609.      But you did not. You either left a method out, or (more likely) you
  1610.      misspelled its name. Perhaps you wrote "ActionListener" instead of
  1611.      "actionListener".
  1612.  
  1613.      So the compiler did not find the method to fulfill the interface. Since
  1614.      there was a method promised but not supplied, the compiler thinks you
  1615.      were aiming at an abstract class, and it prints an error message
  1616.      accordingly.
  1617.  
  1618.   4. (Sect. 5) Variable may not have been initialized.
  1619.  
  1620.          URL test;
  1621.          try {
  1622.           test = new URL("http://osprey.avs.dec.com");
  1623.          } catch (MalformedURLException e) {
  1624.           System.out.println("bad URL:" + e.getMessage());
  1625.          }
  1626.          System.out.println("this is url " + test);
  1627.  
  1628.  
  1629.      [*] The compiler will warn you if you use a variable before it is
  1630.      certain to have been initialized (not just with the default value)
  1631.      since this means you probably forgot to set it.
  1632.  
  1633.      In the case of exceptions, you have to consider that the flow of
  1634.      control may terminate abruptly, with no operations completed. In the
  1635.      example above, if an exception is raised in the try clause, variable
  1636.      test will not be assigned a value, yet you are using it after the catch
  1637.      clause. One solution would be to declare test with an explicit initial
  1638.      value of null, but this works only because toString() works on a null
  1639.      reference. (toString() is invoked implicitly by operator + with String
  1640.      operand.)
  1641.  
  1642.      Always initialize to a value that will work notwithstanding exceptions
  1643.      being thrown.
  1644.  
  1645.   5. (Sect. 5) No constructor {superclass}()
  1646.      I extended the class called Frotz, and the compiler is giving me an
  1647.      error message "No constructor Frotz()" in the child class. Why?
  1648.  
  1649.      [*] When you define a constructor for a class, the compiler inserts a
  1650.      call to the superclass' parameterless constructor unless you explicitly
  1651.      call the superclass' constructor at the start of your constructor. If
  1652.      the superclass doesn't *have* a parameterless constructor, the compiler
  1653.      emits a message to that effect. The solution is usually to call the
  1654.      superclass' constructor at the start of your constructor.
  1655.  
  1656.   6. (Sect. 5) No constructor matching MyCheckbox(myApplet)
  1657.  
  1658.          MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
  1659.          found in class MyCheckbox.
  1660.  
  1661.          bp1 = new MyCheckbox(this);
  1662.          ^
  1663.  
  1664.      [*] If a compiler isn't finding a constructor you thought you created,
  1665.      check whether you gave a return value to the method (remember,
  1666.      constructors have no return value). E.g.,
  1667.  
  1668.          public void MyCheckbox( Container parent )
  1669.  
  1670.  
  1671.      If you did, the compiler will think it is an ordinary method, not a
  1672.      constructor. This is a common mistake and hard to spot.
  1673.  
  1674.   7. (Sect. 5) Type expected {public method variable}
  1675.  
  1676.          public static void main(String[] args) {
  1677.          ^
  1678.          Statement expected.
  1679.          public static final float Conversion_Factor = 39.37;
  1680.          ^
  1681.          Type expected.
  1682.  
  1683.      [*] Argument and variable declarations inside methods are never public
  1684.      or static because they are local to a method. (Before JDK 1.1 they
  1685.      couldn't be final either, but there was no good reason for that
  1686.      restriction and it was dropped.) If you have public or static
  1687.      variables, move them outside the method. They are usually put at the
  1688.      beginning of the class.
  1689.  
  1690.   8. (Sect. 5) Can't access protected method clone in class java.lang.Object
  1691.  
  1692.          T.java:96: Can't access protected method clone in
  1693.          class java.lang.Object. OtherT is not a subclass of
  1694.          the current class.
  1695.  
  1696.      [*] Object.clone() is protected because subclasses might want to
  1697.      restrict access to cloning, and if Object.clone() were declared public,
  1698.      subclasses could never make it more restrictive. The subclass can make
  1699.      access to the clone() operation less restrictive.
  1700.      This means that a method can clone its own objects, but a method cannot
  1701.      clone objects of another class, unless you do something like:
  1702.  
  1703.          class SomeObject implements Cloneable {
  1704.              public Object clone()
  1705.                  throws CloneNotSupportedException {
  1706.                  return super.clone();
  1707.              }
  1708.          }
  1709.  
  1710.  
  1711.      i.e., override clone() to make it public, and call the superclass
  1712.      clone().
  1713.  
  1714.          class Foo {
  1715.           Bar bar;
  1716.           Foo (Bar b) {
  1717.               try {bar = (Bar) b.clone();}
  1718.               catch (Exception e) {}
  1719.           }
  1720.          ...
  1721.          class Bar implements Cloneable {
  1722.           public Object clone()
  1723.               throws java.lang.CloneNotSupportedException {
  1724.               return super.clone();
  1725.           }
  1726.          }
  1727.  
  1728.  
  1729.      Another refinement is to note that Object.clone() only throws a
  1730.      CloneNotSupportedException when the object doesn't implement Cloneable.
  1731.      Since you control what your classes do and don't implement, you can
  1732.      ensure that Cloneable classes implement the interface, and you don't
  1733.      need to make the overridden clone() throw the exception.
  1734.  
  1735.          public class X implements Cloneable {
  1736.              public Object clone() { // no throws
  1737.                  try {
  1738.                            // in case members need cloning
  1739.                      X c = (X)super.clone();
  1740.                      return c;
  1741.                     } catch (CloneNotSupportedException e) {
  1742.                     // should not happen, because of Cloneable
  1743.                         throw new InternalError();
  1744.                     }
  1745.                 }
  1746.          }
  1747.  
  1748.  
  1749.   9. (Sect. 5) Deprecated methods
  1750.      What does "deprecated" mean? I got this in a compiler error message.
  1751.  
  1752.      [*] "Deprecated" means you are using an older API, that Sun has
  1753.      replaced with a newer one (usually to follow more consistent naming
  1754.      conventions). Deprecated methods are not recommended for use. They are
  1755.      supported in the short term, but your code should be updated with the
  1756.      new. To update your code, compile your old code using javac's
  1757.      "-deprecation" option to list deprecated methods, then find the
  1758.      replacement methods in the current HTML API documentation for the old
  1759.      deprecated methods.
  1760.      As an example of a deprecated API, Component.size() was replaced by
  1761.      Component.getSize().
  1762.  
  1763.      See also
  1764.      http://java.sun.com/products/jdk/1.1/docs/guide/
  1765.      misc/deprecation/index.html, "1.1 Deprecated Methods"
  1766.      and
  1767.      http://java.sun.com/products/jdk/1.1/docs/guide/
  1768.      awt/DeprecatedMethods.html, "Deprecated methods in the 1.1 AWT"
  1769.  
  1770.  10. (Sect. 5) double y = sin(90);
  1771.      What's wrong? That code provokes compiler messages.
  1772.  
  1773.      [*] You need to write it this way:
  1774.  
  1775.          double cvtDegToRad = Math.PI/180;
  1776.          double x = 90*cvtDegToRad;
  1777.          double y = Math.sin(x);
  1778.  
  1779.  
  1780.      sin is a static method of the Math class that takes radians. You need
  1781.      to use the "Math" classname, e.g. Math.sin instead of plain sin,
  1782.      because you have to say what class or object these methods belong to.
  1783.  
  1784.      A very common mistake is to assume that importing a class means that
  1785.      you don't have to qualify the names of its members. When you call a
  1786.      method you have to state the name of the class or object it belongs to,
  1787.      regardless of any imports you have done. (Except inside the class
  1788.      itself, obviously).
  1789.  
  1790.      The trig functions are static methods of the Math class, so you give
  1791.      the name of the class in invoking them. Further, the Math class works
  1792.      in radians, not degrees. 360 degrees = 2 pi radians, so use a
  1793.      conversion factor as shown if you are working with degrees.
  1794.  
  1795.  11. (Sect. 5) Can't make static reference to method...
  1796.  
  1797.      [*] Your code probably looks something like this:
  1798.  
  1799.          class myclass {
  1800.              public static void main(String args[]) {
  1801.                myMethod();
  1802.              }
  1803.              public void myMethod() { //some code
  1804.              }
  1805.          }
  1806.  
  1807.  
  1808.      Static (class) methods can only call without qualification other static
  1809.      methods, so you either have to qualify the call in (static) main() to
  1810.      (nonstatic) myMethod() with an object of type myclass, or you have to
  1811.      make myMethod() static.
  1812.  
  1813.      People often forget that even though main is "in" myclass, there is no
  1814.      implicit object when you are in main() because it is static. This
  1815.      happens especially when writing code to run an applet as an
  1816.      application, where you want to call init() and start() from main.
  1817.  
  1818.          public static void main(String[] args) {
  1819.              Applet ma = new myApplet(); // have to create object
  1820.              ma.init();  // use to qualify access to non-static methods
  1821.              ma.start();
  1822.          }
  1823.  
  1824.  
  1825.  12. (Sect. 5) Incompatible type for =. Explicit cast needed...
  1826.  
  1827.          byte b = 0;
  1828.          Incompatible type for =.
  1829.          Explicit cast needed to convert int to byte.
  1830.          b = b + 100;    // compiler error message
  1831.          b += 100;       // works OK
  1832.  
  1833.  
  1834.      [*] Arithmetic expressions are promoted to the type of the longest,
  1835.      floatiest operand in them, or at least to int. The first statement
  1836.      involves the assignment of an expression. The expression is promoted to
  1837.      32 bits, and must be cast back down to 8 bits, like this: b = (byte)
  1838.      (b+100); The second is an operator assignment, and the cast back to
  1839.      byte takes place automatically. The Java Language Specification says
  1840.      that a compound assignment expression of the form E1 op= E2 is
  1841.      equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the
  1842.      type of E1, except that E1 is evaluated only once. (See JLS 15.25.2
  1843.      Compound Assignment Operators) The compile-time narrowing of constants
  1844.      means that code such as:
  1845.  
  1846.          byte theAnswer = 42;
  1847.  
  1848.  
  1849.      is allowed, with no cast necessary. (See JLS 5.2 Assignment Conversion)
  1850.  
  1851.      Other sites:
  1852.      JLS 5.2 Assignment Conversion
  1853.      JLS 15.25.2 Compound Assignment Operators
  1854.  
  1855.  13. (Sect. 5) Class {package}.{class} not found in type declaration.
  1856.      I am trying to compile file "{class2}.java" in a package, and I get
  1857.      this compiler error. {class2}.java refers to {package}.{class}, but the
  1858.      file {class}.java and {class2}.java are in the same {package}
  1859.      directory, which is the current directory and which is in the CLASSPATH
  1860.      variable. Both files have "package {package};" at the top of the file.
  1861.      What's the problem?
  1862.  
  1863.      [*] When the source refers to classes in packages, the CLASSPATH has to
  1864.      point to the root of the package/directory hierarchy for a reference to
  1865.      resolve correctly. This is true even for source files in the same
  1866.      package (and directory). I.e., assuming {class} and {class2} are both
  1867.      in {package}, {class} can't make a reference to {class2} unless the
  1868.      CLASSPATH is set so javac can find {package}/{class2}.java. It should
  1869.      make no difference what directory you are in when you invoke javac,
  1870.      unless you are relying on "." in the CLASSPATH to point to the package
  1871.      root or are specifying the source file with a relative path (e.g.,
  1872.      {package}/{class}.java).
  1873.  
  1874.      Some examples, assuming
  1875.         o - Foo.java and Bar.java are in /java/source/pack/
  1876.         o - Both have "package pack;" as the first statement
  1877.         o - Foo.java includes "Bar b = new Bar();"
  1878.  
  1879.          # solaris ksh
  1880.          $ alias jc=/java/jdk11/bin/javac
  1881.          $ CLASSPATH=/java/source/
  1882.          $ jc /java/source/pack/*.java  # works fine
  1883.          $ cd /java/source/pack
  1884.          $ CLASSPATH=.
  1885.          $ jc *.java         # fails - Foo.java can't find class Bar
  1886.          $ cd ..             # now . is package root, /java/source/
  1887.          $ js pack/*.java    # works
  1888.  
  1889.  
  1890.  14. (Sect. 5) public class "Foo" must be defined in "Foo.java"
  1891.      I get this message even though it is in Foo.java. What gives?
  1892.  
  1893.      [*] Javac verifies that a public class is defined in a file of the same
  1894.      name (e.g., that public class Foo is defined in Foo.java). Two things
  1895.      you can check:
  1896.  
  1897.      First, make sure the case matches exactly. public class Foo cannot be
  1898.      in foo.java; it has to be in Foo.java.
  1899.  
  1900.      Second, are you using MKS on win32? Javac on win32 assumes you are
  1901.      using the DOS path separator (\) even though MKS accepts the Unix path
  1902.      separator (/). When javac tries to parse a your Unix-style path, it
  1903.      won't produce the correct filename, the match will fail, and it will
  1904.      emit an error. You have to use the DOS path separator (\), which must
  1905.      be escaped in MKS - e.g., "javac H:\\source\\package\\Foo.java".
  1906.      Alternatively, you can traverse to each source directory and avoid
  1907.      pathnames altogether.
  1908.  
  1909.                        -------------------------------
  1910.  
  1911. 6. Java Language Issues
  1912.  
  1913.      How-to
  1914.  
  1915.   1. (Sect 6.) How do I compare two Strings?
  1916.  
  1917.      if (s1 == s2)
  1918.  
  1919.      is giving me funny results.
  1920.  
  1921.      [*] The comparison using "==" on objects, such as Strings, is asking,
  1922.      "Do these two objects have the same reference?" Do they have the same
  1923.      address, and hence are the same object? What you really want to do is
  1924.      ask, "Do these two Strings have the same *contents*?"
  1925.      Compare String contents with any of the following:
  1926.  
  1927.          if (s1.equals(s2) )
  1928.          if (s1.equalsIgnoreCase(s2) )
  1929.          if (s1.startsWith(s2) )
  1930.          if (s1.endsWith(s2) )
  1931.          if (s1.regionMatches(s1_offset, s2, s2_offset, length) )
  1932.          if (s1.compareTo(s2) < 0)
  1933.  
  1934.  
  1935.      (There are other ways, too.)
  1936.      Note that you can do this with literals:
  1937.  
  1938.      if ("apple".equals(s2) ) ...
  1939.  
  1940.  
  1941.      If you compare these the other way round, like this:
  1942.  
  1943.      if ( s2.equals("apple") ) ...
  1944.  
  1945.  
  1946.      and s2 is null, you will get a null pointer exception.
  1947.  
  1948.   2. (Sect. 6) How do you get the code value of a char?
  1949.      I would like to transform a char into the corresponding int value, that
  1950.      represents the code value of the char. How?
  1951.  
  1952.      [*] Like this.
  1953.  
  1954.          char c = 'A';
  1955.          int i = c;
  1956.  
  1957.  
  1958.      Going the other way is just
  1959.  
  1960.          c = (char) i;
  1961.  
  1962.  
  1963.      This question crops up so frequently because the BASIC language uses
  1964.      functions to map characters into ints, ASC( 'A' ) => 65 causing BASIC
  1965.      programmers to seek the corresponding Java functions. The same is true
  1966.      for Pascal, Ada, and other languages.
  1967.  
  1968.   3. (Sect. 6) Why does b >>>= 1 give me the same result as b >>= 1?
  1969.  
  1970.      [*] ">>" is a "signed" or "arithmetic" shift, namely, it replicates the
  1971.      sign bit on the left as it shifts.
  1972.      The ">>>" operator is an "unsigned" or "logical" shift; it does a shift
  1973.      right and zero fill. However, ">>>" looks like it does a signed shift
  1974.      with negative bytes and shorts, where int promotion alters the sign.
  1975.  
  1976.      This occurs when you have a non-canonical type, byte, or short, with a
  1977.      negative value, e.g.
  1978.  
  1979.          byte b = -15; // 0xf1
  1980.          b = (byte) b >>> 4; // why isn't b 0x0f ?
  1981.  
  1982.  
  1983.      The initial expectation is that an unsigned shift right of 0xf1 would
  1984.      successively be (in binary)
  1985.  
  1986.          0111_1000 then
  1987.          0011_1100 then
  1988.          0001_1110 then
  1989.          0000_1111
  1990.  
  1991.  
  1992.      But that doesn't happen. The rules of arithmetic in Java say that all
  1993.      operands are converted at least to int before the operation (and
  1994.      possibly to a more capacious type). That means our byte is promoted to
  1995.      an int, so instead of shifting 0xf1, we are shifting 0xfffffff1. If you
  1996.      shift right unsigned 4 places, you get 0x0fffffff. When you cast that
  1997.      to a byte it becomes 0xff, or -1.
  1998.  
  1999.      The bottom line is that the final result is the same as if you had
  2000.      performed the signed shift because the unsigned shift applied to the
  2001.      intermediate int, not to the original byte. This anomaly means that
  2002.      ">>>" is useless for negative bytes and shorts. It is probably safer
  2003.      and clearer not to use it at all, but to mask and shift instead:
  2004.  
  2005.          // not recommended
  2006.          byte b = -15;
  2007.          b = (byte) (b>>>4);
  2008.          System.out.println("b= "+Integer.toHexString(b) );
  2009.          // recommended
  2010.          b = -15;
  2011.          b = (byte) ( (b & 0xFF) >> 4 );
  2012.          System.out.println("b= "+Integer.toHexString(b) );
  2013.  
  2014.  
  2015.   4. (Sect. 6) Why does the <unexpected> happen in floating point?
  2016.  
  2017.      [*] There are several unexpected things that seem to bite programmers
  2018.      with floating point. This is almost always a result of the programmer
  2019.      not being fully conversant with floating point arithmetic in general,
  2020.      rather than a problem relating to Java.
  2021.  
  2022.      If you seem to be having problems with floating point, the problem
  2023.      probably stems from the fact that floating-point arithmetic is
  2024.      inherently imprecise. You can expect up to 7 digits of precision with
  2025.      floats and 16 digits with doubles. However, that does not mean that a
  2026.      number that can be exactly represented in 7 digits decimal or can be
  2027.      exactly represented as a binary floating point number. On the contrary,
  2028.      that is usually not the case.
  2029.  
  2030.      Additionally, when Java converts floating point numbers to a String, as
  2031.      is done when they are output, enough digits are printed so the number
  2032.      can be read back in with no loss of precision. For this reason, you may
  2033.      see more "inaccuracies" in floating point output than you are used to.
  2034.      This policy actually gives you more consistent results than on a system
  2035.      where floating point output is deliberately rounded to make the output
  2036.      "pretty".
  2037.  
  2038.      There is a limitation of FP in JDK 1.0 (fixed in JDK 1.1). Namely, when
  2039.      you output a floating point number in Java 1.0, the result is
  2040.      system-dependent and contains no more than six digits after the decimal
  2041.      point. This bug is fixed in Java 1.1.
  2042.  
  2043.      For more information and detailed specifications on how Java deals with
  2044.      floating point, see the URLs listed below.
  2045.  
  2046.      Other sites:
  2047.      What Every Computer Scientist Should Know About Floating Point.
  2048.      http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities
  2049.  
  2050.      JLS 4.2.3 Floating-Point Types and Values
  2051.      JLS 4.2.4 Floating-Point Operations
  2052.      JLS 3.10.2 Floating-Point Literals
  2053.      JLS 5.2.3 Narrowing Primitive Conversions
  2054.  
  2055.      If you want the rounded floating point output that most languages have,
  2056.      use the new java.text package of Java 1.1 to limit the number of digits
  2057.      that are output. If you need more precision than about 16 digits, use
  2058.      the BigInteger and BigDecimal classes of Java 1.1.
  2059.  
  2060.      Understanding the Java Language
  2061.  
  2062.   5. (Sect. 6) How can I program linked lists if Java doesn't have pointers?
  2063.  
  2064.      [*] Of all the misconceptions about Java, this is the most egregious.
  2065.      Far from not having pointers, in Java, object-oriented programming is
  2066.      conducted exclusively with pointers. In other words, objects are only
  2067.      ever accessed through pointers, never directly. The pointers are termed
  2068.      "references" and they are automatically dereferenced for you.
  2069.  
  2070.      Java does not have pointer arithmetic or untyped casting. By removing
  2071.      the ability for programmers to create and modify pointers in arbitrary
  2072.      ways, Java makes memory management more reliable, while still allowing
  2073.      dynamic data structures. Also note that Java has NullPointerException,
  2074.      not NullReferenceException.
  2075.  
  2076.      A linked list class in Java might start like this:
  2077.  
  2078.          public class LinkedList {
  2079.              public LinkedList head;
  2080.              public LinkedList next;
  2081.              public Object data;
  2082.              public LinkedList advanceToNext(LinkedList current) { ...
  2083.          }
  2084.  
  2085.  
  2086.      Another choice for a linked list structure is to use the built-in class
  2087.      java.util.Vector which accepts and stores arbitrary amounts of Object
  2088.      data (as a linked list does), and retrieves it by index number on
  2089.      demand (as an array does). It grows automatically as needed to
  2090.      accommodate more elements. Insertion at the front of a Vector is a slow
  2091.      operation compared with insertion in a linked list, but retrieval is
  2092.      fast. Which is more important in the application you have?
  2093.  
  2094.   6. (Sect. 6) Are parameters in Java passed by value or by reference?
  2095.  
  2096.      [*] All parameters (values of primitive types and values that are
  2097.      references to objects) are passed by value. (See JLS 8.4.1 Formal
  2098.      Parameters) However this does not tell the whole story, since objects
  2099.      are always manipulated through reference variables in Java. Thus one
  2100.      can equally say that objects are passed by reference (and the reference
  2101.      variable is passed by value). This is a consequence of the fact that
  2102.      variables do not take on the values of "objects" but values of
  2103.      "references to objects" as described in the previous question on linked
  2104.      lists.
  2105.  
  2106.      Bottom line: The caller's copy of primitive type arguments (int, char,
  2107.      etc.) _do not_ change when the corresponding parameter is changed.
  2108.      However, the fields of the caller's object _do_ change when the called
  2109.      method changes the corresponding fields of the object (reference)
  2110.      passed as a parameter.
  2111.  
  2112.      Also in this FAQ:
  2113.      How can I program linked lists if Java doesn't have pointers?
  2114.      Other sites:
  2115.      JLS 8.4.1 Formal Parameters
  2116.  
  2117.   7. (Sect. 6) What are "class literals"?
  2118.  
  2119.      [*] A feature introduced in JDK 1.1. They are literals of type "Class"
  2120.      that hold a value representing any class. There are even values to
  2121.      represent "void" and an array, like this:
  2122.  
  2123.          Class myCl1 = Character.class;
  2124.          Class myCl2 = Void.class;
  2125.          Class myCl3 = Object.class;
  2126.          Class myCl4 = String[].class;
  2127.          Class myCl5 = int[][].class;
  2128.  
  2129.  
  2130.      You might use it like this:
  2131.  
  2132.          Class cl = thing.getClass();
  2133.          if (cl.equals(myCl1))
  2134.          System.out.println("It's a Character class");
  2135.  
  2136.  
  2137.      Note that a class literal
  2138.  
  2139.              Component.class
  2140.  
  2141.  
  2142.      is the equivalent of
  2143.  
  2144.              Class.forName("java.awt.Component")
  2145.  
  2146.  
  2147.      The second can throw an exception, but the first cannot. If you don't
  2148.      know the name of the class when you write the code, you cannot use the
  2149.      first form.
  2150.  
  2151.   8. (Sect. 6) What are the naming conventions in Java?
  2152.  
  2153.      [*] The naming conventions are straightforward:
  2154.        1. Package names are guaranteed uniqueness by using the Internet
  2155.           domain name in reverse order: com.javasoft.jag - the "com" or
  2156.           "edu" (etc.) part used to be in upper case, but now lower case is
  2157.           the recommendation.
  2158.        2. Class and interface names are descriptive nouns, with the first
  2159.           letter of each word capitalized: PolarCoords. Interfaces are often
  2160.           (not always) called "something-able", e.g. "Runnable", "Sortable".
  2161.           Caution: java.util.Observable is not an interface, though
  2162.           java.util.Observer is. These two are poorly designed.
  2163.        3. Object and data (field) names are nouns/noun phrases, with the
  2164.           first letter lowercase, and the first letter of subsequent words
  2165.           capitalized: currentLimit
  2166.        4. Method names are verbs/verb phrases, with the first letter
  2167.           lowercase, and the first letter of subsequent words capitalized:
  2168.           calculateCurrentLimit
  2169.        5. Constant (final) names are in caps: UPPER_LIMIT
  2170.        6. Also in the FAQ:
  2171.           Where can I find a Java style guide on naming conventions?
  2172.           Other sites:
  2173.           JLS 6.8 Naming Conventions
  2174.  
  2175.   9. (Sect. 6) Should I prefer importing {package}.{class} over {package}.*?
  2176.  
  2177.      Does it make a difference to the class file in any way, if I import a
  2178.      package versus use the full name, i.e.
  2179.  
  2180.          import java.rmi.server.*;
  2181.          ...
  2182.          RemoteObject ro;
  2183.  
  2184.      versus:
  2185.  
  2186.          java.rmi.server.RemoteObject ro;
  2187.  
  2188.      [*] No, it makes no difference to the class files or runtime speed.
  2189.      Import is just a shorthand for quoting the full name package and class
  2190.      name (as in the examples in the question). Importing a class does not
  2191.      cause the class to be loaded at run time. There is no runtime penalty
  2192.      for using the * form of import. The class file will contain the name of
  2193.      the packages it uses, and the loader will look for those classes as
  2194.      needed at runtime.
  2195.  
  2196.      At compile time, the different forms of import may or may not make a
  2197.      difference to compile time. Such a difference is likely to be
  2198.      negligible, and should not be a factor in which form of import you use.
  2199.  
  2200.      However, there are style advantages. Some say that stating which
  2201.      classes you are importing can help program readability. In a program
  2202.      with many * import statements, it may take a programmer time to find
  2203.      which package an obscure class is imported from. If you explicitly list
  2204.      each class you import at the top of the program, you document which
  2205.      package each class you use comes from. These people suggest that you
  2206.      use
  2207.  
  2208.      import java.rmi.server.RemoteObject;
  2209.  
  2210.  
  2211.      in preference to:
  2212.  
  2213.      import java.rmi.server.*;
  2214.  
  2215.  
  2216.      Other people say that it is clearer still to use the full package and
  2217.      class name, at the point where you use classes in other packages.
  2218.      These people suggest that you use:
  2219.  
  2220.      java.rmi.server.RemoteObject ro;
  2221.  
  2222.  
  2223.      But that gets a little lengthy when you instantiate:
  2224.  
  2225.              java.rmi.server.RemoteObject ro
  2226.                        = new java.rmi.server.RemoteObject();
  2227.  
  2228.  
  2229.      You always have the option of stating the full package and class name,
  2230.      whether you use import or not.
  2231.  
  2232.      Another good reason not to use the * form is when you are importing two
  2233.      packages that have classes of the same name and you want to use only
  2234.      one of those classes. E.g.
  2235.  
  2236.          import com.sun.*;
  2237.          import com.ms.*;
  2238.  
  2239.  
  2240.      where there is a class called Modem in both those packages. If you use
  2241.      the * form of import, you import both of the Modem classes and then
  2242.      must fully qualify the class each time you use it, to say which of the
  2243.      two you mean.
  2244.  
  2245.      In Java 1.0, if you import a class that has the same name as a class
  2246.      defined in that source file, you will get an error that the class names
  2247.      clash. In Java 1.1, the local class will be used when the package name
  2248.      is not given; to use the imported class, you have to use the full
  2249.      package name.
  2250.  
  2251.      The best advice is to write the program so that it is as readable as
  2252.      possible. Where you have a group of well-known classes, as in java.awt,
  2253.      there is no reason not to use "import java.awt.*;"
  2254.  
  2255.  10. (Sect. 6) How can I use Math.cos() etc. without the prefix "Math."?
  2256.      Is there some declaration that I can use to make "acos", "cos", "sin",
  2257.      etc. (from java.lang.Math) recognizable in my own class, so I don't
  2258.      have to prefix "Math." to them?
  2259.  
  2260.      [*] No. There is no good alternative. There are several bad
  2261.      alternatives:
  2262.        1. Using "import" doesn't work.
  2263.           The import stament only imports packages, subpackages, and
  2264.           classes, not class members. This doesn't work:
  2265.  
  2266.                   import java.lang.Math.*;
  2267.  
  2268.  
  2269.        2. Minimizing class name usage is unclear and bad style.
  2270.           - You could wrap the functions in your own class.
  2271.  
  2272.               double sin(double x) {
  2273.                   return Math.sin(x);
  2274.               } // etc. for each function
  2275.  
  2276.  
  2277.           But you'd have to use your class name everywhere but inside your
  2278.           class, so it doesn't help.
  2279.           - You can make a null reference to the Math class and use it to
  2280.           refer to the static methods. Declare
  2281.  
  2282.               java.lang.Math M = null;
  2283.               angle = M.cos(i);
  2284.  
  2285.  
  2286.           Besides not being clear, this invites abuse and errors.
  2287.  
  2288.           - You could inherit the names
  2289.           If java.lang.Math were not final and your class did not extend
  2290.           another class, you could have your class extend Math, to bring the
  2291.           namespace in. However, it is poor OOP style to use inheritance to
  2292.           obtain a name abbreviation rather than to express a type
  2293.           hierarchy.
  2294.  
  2295.  11. (Sect. 6) Why is there a standard JNI?
  2296.  
  2297.      [*] JNI is the Java Native Interface. It defines the way that a Java
  2298.      program can call C programs. The industry has agreed on, and Sun has
  2299.      codified, JNI as the standard. Microsoft shuns the standard and uses a
  2300.      protocol of its own called Raw Native Interface, RNI.
  2301.  
  2302.      You might think that once a Java program uses JNI, portability is lost,
  2303.      and hence it doesn't matter if vendors diverge from the JNI standard.
  2304.      Not so. Code that accesses a native library using JNI can run on any VM
  2305.      that supports JNI, so it's portable across VMs on the same platform.
  2306.      Further, you can port a native library to all platforms Java supports
  2307.      (indeed, this is how Sun implements the Java Platform), so JNI
  2308.      _enables_ cross-platform development where it's necessary to use
  2309.      platform-specific idioms for certain functionality.
  2310.  
  2311.      Conversely, code that uses RNI can only run on Microsoft's VMs on the
  2312.      win32 platform. Microsoft's RNI has the effect of limiting RNI programs
  2313.      to the Microsoft VM. Further, Microsoft's failure to support JNI locks
  2314.      out JNI-based functionality on Windows. Microsoft's non-standard RNI is
  2315.      the reason that programs using the Microsoft JVM cannot use the
  2316.      standard Java jdbc-odbc library. That library has a piece written in C.
  2317.      It works for all JVMs except Microsoft's.
  2318.  
  2319.      The standard JNI thus has two purposes:
  2320.        1. Source code compatibility between different platforms.
  2321.        2. Binary code compatibility between different JVMs on the same
  2322.           platform.
  2323.      Microsoft's use of RNI locks in programmers who use it, and Microsoft's
  2324.      failure to support JNI locks out programmers who don't use RNI. Users
  2325.      can't run standard JNI applications on Microsoft VMs, or RNI
  2326.      applications on non-Microsoft VM's. As a result, since most users will
  2327.      support only one VM, they'll be locked in to complementary software -
  2328.      in the case of Microsoft, a proprietary standard. A standard JNI means
  2329.      that you can use any standard JVM to run your code on this platform.
  2330.  
  2331.  12. (Sect. 6) How do I find out more about JNI? How do I find out more
  2332.      about Java Anything?
  2333.  
  2334.      [*] Taking the questions one at a time. Use of JNI detracts from
  2335.      program portability. So you would only do it when you need some
  2336.      critical single-platform effect. The documentation on JNI is at:
  2337.      http://java.sun.com/docs/books/tutorial/native1.1/index.html
  2338.  
  2339.      If your interest extends to reading a book on JNI, a good one is
  2340.      "Essential JNI Java Native Interface" by Rob Gordon; ISBN
  2341.      0-13-679895-0. Available from Amazon.com and book outlets everywhere.
  2342.  
  2343.      In general, if you want to find out about topic "X" in Java, your first
  2344.      stop should be to search the http://java.sun.com website for "X". For
  2345.      example if you want to know about Internationalization in Java, a
  2346.      search at the site quickly takes you to
  2347.      http://java.sun.com/products/jdk/1.1/docs/guide/intl/intlTOC.doc.html.
  2348.  
  2349.  13. (Sect. 6) How do I get unsigned ints in Java?
  2350.  
  2351.      [*] Java doesn't have unsigned ints. The reason is that this is a
  2352.      poorly designed area of C. The rules for what type you end up with when
  2353.      you mix signed and unsigned in expressions are complicated, and they
  2354.      changed between K&R and ANSI C (you might have heard this under the
  2355.      name "unsigned preserving vs. value preserving"). Worse, they depended
  2356.      on the underlying hardware, so they varied from platform to platform,
  2357.      causing bugs in all kinds of unexpected places. The book "Expert C
  2358.      Programming" goes into this in more depth (page 25). So, to avoid
  2359.      bringing over the hidden complexities, Java does not bring over
  2360.      unsigned types from C.
  2361.      Use type char if you are OK with 16-bit unsigned quantities. Otherwise,
  2362.      go to the next larger type and use masking. Specifically, to convert an
  2363.      int to its unsigned representation, use:
  2364.  
  2365.              ((long)i) & 0x00000000FFFFFFFFL
  2366.  
  2367.  
  2368.      This promotes the signed int to long (with sign extension) then chops
  2369.      off the sign-extension, leaving it as a positive 32-bit quantity held
  2370.      in a 64-bit type.
  2371.      Also worth noting is that if you're going to work with unsigned bytes,
  2372.      int is a more efficient larger type to use than short or char, since
  2373.      smaller values have to be promoted to int to do any arithmetic or
  2374.      testing on them.
  2375.  
  2376.  14. (Sect. 6) What happened to "private protected"?
  2377.  
  2378.      [*] It first appeared in JDK 1.0 FCS (it had not been in the betas).
  2379.      Then it was removed in JDK 1.0.1. It was an ugly hack syntax-wise, and
  2380.      it didn't fit consistently with the other access modifiers. It never
  2381.      worked properly: in the versions of the JDK before it was removed,
  2382.      calls to private protected methods were not dynamically bound, as they
  2383.      should have been. It added very little capability to the language. It's
  2384.      always a bad idea to reuse existing keywords with a different meaning.
  2385.      Using two of them together only compounds the sin.
  2386.  
  2387.      The official story is that it was a bug. That's not the full story.
  2388.      Private protected was put in because it was championed by a strong
  2389.      advocate. It was pulled out when he was overruled by popular
  2390.      acclamation.
  2391.  
  2392.      Inheritance
  2393.  
  2394.  15. What are the differences between an interface and an abstract class?
  2395.  
  2396.      [*] Some use a semantic distinction: an abstract superclass models the
  2397.      "is" relationship, while an interface models the "has" relationship.
  2398.      The rule would thus be, if it's a subtype, inherit; otherwise,
  2399.      implement. But where the object boundaries are themselves at stake,
  2400.      it's circular to state this unless there are real-world metaphors to
  2401.      distinguish the objects from their properties and parents. So where
  2402.      there are no real-world metaphors, you have to understand the practical
  2403.      differences in Java (esp. vs. C++).
  2404.  
  2405.      Most differences between interfaces and abstract classes stem from
  2406.      three characteristics:
  2407.        1. Both define method signatures that a derived class will have.
  2408.        2. An abstract class can also define a partial implementation.
  2409.        3. A class can implement many interfaces, but inherit from only one
  2410.           class.
  2411.  
  2412.      In greater detail, these topics are:
  2413.        1. Method signatures Both interfaces and abstract classes permit one
  2414.           to treat the derived-type class as the derived-from-type class.
  2415.           Both define a set of available methods in a way that can be
  2416.           enforced by the type-checking mechanism. This is typically used to
  2417.           permit different (derived) types to behave in the same way (as
  2418.           what they are derived from - i.e., they all support particular
  2419.           methods). For example, all java.* types can be printed as Strings
  2420.           because Object, the superclass of all java.* types, has a
  2421.           toString() method. Similarly, all types that implement the
  2422.           Observable interface can be passed an Observer to signal when an
  2423.           event has occurred. This permits an algorithm or service to
  2424.           operate on different (derived) types as if they were the same
  2425.           (derived-from) type.
  2426.           This mechanism supports not only polymorphism (one object treated
  2427.           as another), but differentiation. In either case, the (derived)
  2428.           types can implement the method in the way appropriate to that
  2429.           type. However, you're not likely to override inherited
  2430.           functionality, but you must implement interface methods, so if you
  2431.           expect significant differentiation, then an interface might be
  2432.           warranted.
  2433.           Finally, this mechanism supports a weak variant of access control.
  2434.           Only inherited methods are available to callers who only have a
  2435.           reference to the superclass or interface type. It's weak because
  2436.           they can attempt a narrowing cast if they know their target type.
  2437.           Nonetheless, it reduces some complexity.
  2438.        2. Inheriting implementation Inheriting an implementation is useful
  2439.           where the code should be shared. This happens where derived types
  2440.           vary the functionality only a little bit, or where a complex set
  2441.           of method interfaces can through mutual reference be implemented
  2442.           with relatively few methods that can be implemented by derived
  2443.           types. You can also reuse code by having your class use or keep an
  2444.           object of another type that implements that code, but that doesn't
  2445.           permit your callers to treat you in a particular way. To both
  2446.           "get" functionality and to be treated "as" the superclass are the
  2447.           essentials of the type/subtype relationship.
  2448.        3. Java's rule of single inheritance Java differs from C++ in
  2449.           permitting only single inheritance. This makes for some difficult
  2450.           choices, if you would like to share combinations of inherited
  2451.           functionality and polymorphism from more than one source. However,
  2452.           it does reinforce the notion of inheritance as a subtyping (is)
  2453.           relationship, and implicitly that type relationships form a tree
  2454.           rather than a network.
  2455.  
  2456.      Other differences to consider:
  2457.        1. Abstract class implementations may include fields
  2458.        2. Interfaces may include final data members
  2459.        3. It is slightly slower to call an implemented method via an
  2460.           a superclass method via a subclass reference (i.e., where the
  2461.           subclass does not override the method). There is almost no penalty
  2462.           for calling a subclass method via a superclass reference. (All are
  2463.           compared to a direct method call, i.e., calling the derived class
  2464.           method via a derived class reference).
  2465.  
  2466.  16. (Sect. 6) How do static methods interact with inheritance?
  2467.  
  2468.      [*] Static (per-class, rather than per-object) methods do not
  2469.      participate in overriding (choosing the right method at runtime based
  2470.      on the class of the object). Probably the best and simplest way to
  2471.      think about this (and to write your code) is to write every invocation
  2472.      of a static method using the fully qualified class name:
  2473.  
  2474.          class A {
  2475.          public static method1() {
  2476.                  A.method2();
  2477.              }
  2478.          public static method2() {
  2479.              }
  2480.          }
  2481.  
  2482.          class B extends A {
  2483.              public static method3() {
  2484.                  A.method1();
  2485.              }
  2486.              public static method2() {
  2487.              }
  2488.          }
  2489.  
  2490.  
  2491.      Now it is perfectly clear that the static method2() that is called is
  2492.      A.method2(), not B.method2(). A.method2() will be called regardless of
  2493.      whether you use the fully-qualified class name or not, but using "A."
  2494.      makes it obvious to all.
  2495.  
  2496.  17. (Sect. 6) Why is the String class final? I often want to override it.
  2497.  
  2498.      [*] Being final guarantees that instances of String are immutable. (The
  2499.      String class implements immutable objects, but if it were not final it
  2500.      would be possible to write a subclass of String which permitted
  2501.      instances to be changed.) Strings need to be immutable for efficiency
  2502.      and security.
  2503.  
  2504.      As for efficiency, Strings are very commonly used, even behind the
  2505.      scenes by the Java compiler. Efficiency gains in the String class yield
  2506.      big dividends. If no one can change a String, then you never have to
  2507.      worry about who else has a reference to your String. It's easier to
  2508.      optimize accesses to an object that is known to be immutable.
  2509.  
  2510.      Security is a more compelling reason. Before String was changed to be
  2511.      final (while Java 1.0 was still in beta) there was a race condition
  2512.      which could be used to subvert security restrictions. It had to do with
  2513.      having one thread change a pathname while another thread was about to
  2514.      open it.
  2515.  
  2516.      There are other ways to solve these problems, but the designers
  2517.      preferred making String final, particularly since the StringBuffer
  2518.      class is available as an alternative.
  2519.  
  2520.  18. (Sect. 6) If I extend/subclass a class, are the constructors inherited?
  2521.  
  2522.      [*] "Constructor declarations are not members. They are never inherited
  2523.      and therefore are not subject to hiding or overriding." The default
  2524.      constructor is not inherited, but provided. (See JLS 8.6.7 Default
  2525.      Constructors)
  2526.  
  2527.      If you don't give your child class any constructors, a default no-arg
  2528.      constructor that invokes the superclass' constructor is provided for
  2529.      you. If the superclass doesn't have a no-arg constructor, you should
  2530.      create a constructor and call the appropriate superclass constructor.
  2531.  
  2532.      Also in the FAQ:
  2533.      Compiler message No constructor {superclass}()
  2534.  
  2535.      Other sites:
  2536.      JLS 8.6.7 Default Constructors
  2537.  
  2538.  19. (Sect. 6) How can I safely store particular types in general
  2539.      containers?
  2540.      I often want to store particular types of objects but don't want to
  2541.      subclass my basic storage classes to enforce the particular type; that
  2542.      would make for too many subclasses (e.g., IntegerLinkedList,
  2543.      StringLinkedList, etc.).
  2544.  
  2545.      [*] Generic programming in java (the rough equivalent of C++'s
  2546.      templates) works reasonably well since all java classes are subclasses
  2547.      of Object. There is, however one potential problem - there is always a
  2548.      possibility that a generic container may contain different classes of
  2549.      objects.
  2550.  
  2551.      This naturally leads to the question of how to do this in a type-safe
  2552.      way. If you've created a generic LinkedList class, how can you be type
  2553.      safe without having to create a multitude of subclasses
  2554.      (IntegerLinkedList, StringLinkedList, etc.)?
  2555.  
  2556.      One way to handle this would be to offer up an additional constructor
  2557.      in your generic class that takes a parameter of type "Class" and uses
  2558.      that parameter along with Class's "isInstance" method to guarantee that
  2559.      Objects added to the container are the expected type.
  2560.  
  2561.          public class LinkedList {
  2562.              Protected Class type = Object.class;
  2563.  
  2564.              public LinkedList(Class type) { this.type = type; }
  2565.  
  2566.              public void addElement(Object element) throws Exception
  2567.              {
  2568.              if(!type.isInstance( element ))
  2569.                  throw new Exception(
  2570.                       "Expected element of type (" + type    + ")" +
  2571.                       " got element of type ("     + element + ")"   );
  2572.               ...
  2573.               }
  2574.           }
  2575.  
  2576.  
  2577.      Note that the comments in the source for isInstance() refer to a
  2578.      "specified Class parameter", suggesting that you are supposed to write
  2579.      something like:
  2580.  
  2581.              public void addElement(Object element) throws Exception
  2582.          {
  2583.              Class c = element.getClass();
  2584.              if(!type.isInstance(c))
  2585.  
  2586.  
  2587.      This works, but the documentation for isInstance is clear that the
  2588.      parameter should be an Object rather than a Class. Also, note that
  2589.      "Collections" are coming in JDK 1.2, and they provide a much safer and
  2590.      more extensible mechanism. More information about this is available at
  2591.      the Java Developer Connection at the Java website: http://java.sun.com/
  2592.  
  2593.      Method interfaces
  2594.  
  2595.  20. How do I send a variable number of arguments to a method?
  2596.  
  2597.      [*]
  2598.        1. (Easy) Use method overloading to support different parameters.
  2599.           This makes things easy on the caller but can get out of hand if
  2600.           you want to support a wide number and variety of parameter types.
  2601.           You should ask yourself if your code design is well-organized if
  2602.           you need to do this.
  2603.        2. (More complicated) Use arrays. It's even possible to declare
  2604.           arrays inline as shown below:
  2605.  
  2606.               foo("A param",
  2607.                   new Object[] {"param3", "param4", new Integer(5)} );
  2608.            // ...
  2609.  
  2610.            void foo(String param1, Object param2[]) {
  2611.                System.out.println(param1);
  2612.                for (int i = 0; i < param2.length; i++) {
  2613.                    System.out.println(param2[i].toString());
  2614.                }
  2615.            }
  2616.  
  2617.  
  2618.           You can even pass arrays of arrays using this method. Of course,
  2619.           inside the method you need to be able to decode what the arguments
  2620.           are and how you use them.
  2621.        3. Alternatively you can invent a class that just contains all the
  2622.           possible fields you might want to pass into a method (plus
  2623.           booleans to say if each field is set or not), and make an object
  2624.           of that class be a parameter to the method. You can return
  2625.           multiple values from a method the same ways; either have the
  2626.           method return an array or a wrapper object.
  2627.  
  2628.      However, remember the wise words of Professor Alan Perlis, "if your
  2629.      procedure has more than about half a dozen parameters, you probably
  2630.      forgot a few." Passing large numbers of arguments into a function
  2631.      suggests your function is badly organized.
  2632.  
  2633.  21. (Sect. 6) How can I return a different object in a method parameter?
  2634.      How can I pass an object to a method, and have the method change the
  2635.      reference so it points to a different object back in the calling code?
  2636.  
  2637.      [*] There are two ways. The obvious way is "just add another level of
  2638.      indirection". Wrap the object in another class, whose purpose is simply
  2639.      to be passed as a parameter, allowing the nested object reference to be
  2640.      modified.
  2641.      The second alternative is a clearer variant of this. Pass in a single
  2642.      element array. Since arrays are objects, this works.
  2643.  
  2644.              void jfoo(Object ref[]){
  2645.              ref[0] = new Object();
  2646.          }
  2647.          ...
  2648.          Object kludge[] = new Object[1];
  2649.          kludge[0]= myObj;
  2650.          jfoo(kludge);
  2651.          if (kludge[0] == myObj) ...
  2652.          else ...
  2653.  
  2654.  
  2655.      Note that changing a global variable/object inside a method is an
  2656.      egregious programming practice; it usually violates basic OOP
  2657.      constructs.
  2658.  
  2659.  22. (Sect. 6) How do I get multiple return values back from a method?
  2660.  
  2661.      [*] You can just have the function return a Vector. This is
  2662.      particularly convenient when you're not sure how much you are going to
  2663.      be returning, based on what occurs in the method. A Vector is
  2664.      essentially a dynamically-growable array. Regular arrays can't grow
  2665.      after you declare them - you have to declare a bigger array and move
  2666.      the old stuff into it.
  2667.  
  2668.      Arrays
  2669.  
  2670.  23. (Sect. 6) How do I allocate a multidimensional array?
  2671.  
  2672.      [*] There are several ways. If you want a rectangular array, you can
  2673.      allocate the space for the array all at once. The following creates a
  2674.      4x5 array:
  2675.  
  2676.          int arr[][] = new int[4][5];
  2677.  
  2678.  
  2679.      If you want each row to have a different number of columns, you can use
  2680.      the fact that a two-dimensional array is actually an array of arrays.
  2681.      The following code allocates a triangular array:
  2682.  
  2683.          int arr[][] = new int[4][];    // allocate the four row arrays
  2684.          for (int i = 0; i < 4; i++) // initialize each of the four rows
  2685.          arr[i] = new int[i + 1];       // row i has i + 1 columns
  2686.  
  2687.  
  2688.      Note that if you allocate an array of any kind of object (as opposed to
  2689.      primitive type), all the references will be null by default. These null
  2690.      references can result in NullPointerExceptions if you try to
  2691.      dereference them.
  2692.      In other words, after doing:
  2693.  
  2694.          int arr[] = new int[4];
  2695.  
  2696.  
  2697.      you can say
  2698.  
  2699.              if (arr[2] == 0)
  2700.  
  2701.  
  2702.      But after doing
  2703.  
  2704.              Integer Iarr[] = new Integer[4];
  2705.  
  2706.  
  2707.      you must fill in the object reference before using it. E.g.,
  2708.  
  2709.              Iarr[2] = myInt;
  2710.  
  2711.  
  2712.      or
  2713.  
  2714.              arr[2] = new Int(27);
  2715.  
  2716.  
  2717.      before you can say
  2718.  
  2719.              if (Iarr[2].equals(myInt))
  2720.  
  2721.  
  2722.  24. (Sect. 6) How do I copy an array?
  2723.  
  2724.      [*] If the array only contains primitive types or if you want to copy
  2725.      only the object references, not duplicate the objects, then use the
  2726.      method
  2727.  
  2728.          java.lang.System.arraycopy(Object src, int src_position,
  2729.              Object dst, int dst_position, int length);
  2730.  
  2731.  
  2732.      Otherwise, if you want to duplicate the objects, you have to initialize
  2733.      your new array and write a loop that duplicates each object in the old
  2734.      array into the new.
  2735.  
  2736.      Note that the documentation for arraycopy() says that if src and dst
  2737.      refer to the same object, then arraycopy behaves as if the source array
  2738.      elements are copied into a temporary array (i.e., they are preserved).
  2739.      Some interpret this as meaning a temporary array will be so allocated,
  2740.      but that's not Sun's implementation.
  2741.  
  2742.      Other sites:
  2743.      JLS 20.18.16 {java.lang.System.arraycopy()}
  2744.  
  2745.  25. (Sect. 6) How do I clear an array?
  2746.  
  2747.      [*] There is no method to clear an array to 0.0, 0, null, false,
  2748.      '\u0000' etc. When you allocate an array, the elements are set to their
  2749.      default values, but that doesn't help when you want to reuse an array.
  2750.  
  2751.      If you want to set the same array to the same set of values many times,
  2752.      create a template array. Fill it with the reset value, then use
  2753.      System.arraycopy() to copy it into the work array each time you need to
  2754.      set the work array.
  2755.  
  2756.  26. (Sect. 6) What is a fast way to set all elements of an array?
  2757.      I don't want to use a template array. I would like to set all array
  2758.      elements to a given value without duplicating the (possibly large)
  2759.      array.
  2760.  
  2761.      [*] Using a loop that does it one by one is probably 20 to 40 times
  2762.      slower than good old memset() in C.
  2763.  
  2764.      A fast way on many VM's is to set the first byte of the array, then use
  2765.      System.arraycopy() repeatedly to fill the next byte, the next two
  2766.      bytes, the next four bytes, the next eight bytes, etc., and when you
  2767.      get past halfway, fill in the rest.
  2768.  
  2769.          public static void bytefill(byte[] array, byte value) {
  2770.          int len = array.length;
  2771.          if (len > 0)
  2772.          array[0] = value;
  2773.          for (int i = 1; i < len; i += i)
  2774.              System.arraycopy( array, 0, array, i,
  2775.                  ((len - i) < i) ? (len - i) : i);
  2776.          }
  2777.  
  2778.  
  2779.      This is faster on Sun's VM than a simple loop, and probably even faster
  2780.      under JITs because it only performs at most log2(array.length) bounds
  2781.      checks. This is a clever code idiom applying the binary chop algorithm
  2782.      to arrays even when their size is not a power of 2.
  2783.  
  2784.                        -------------------------------
  2785.  
  2786. 7. I/O
  2787.  
  2788.   1. (Sect. 7) How do I read a String/int/boolean/etc from the keyboard?
  2789.  
  2790.      [*] The easiest way is to pick up the source for the 100% pure Java
  2791.      class EasyIn from http://www.afu.com/ (same place as this FAQ). Compile
  2792.      it with your code and use it like this:
  2793.  
  2794.      EasyIn easy = new EasyIn();
  2795.  
  2796.      int i = easy.readInt(); // gets an int from System.in
  2797.      boolean b = easy.readBoolean(); // gets a boolean from System.in
  2798.      double d = easy.readDouble(); // gets a double from System.in
  2799.  
  2800.  
  2801.      ... etc.
  2802.  
  2803.      EasyIn is free, comes with source, and you can do what you like with
  2804.      it, including improve it, and send me back the results.
  2805.  
  2806.      If, instead, you want to "roll your own" code (why?!), in JDK 1.0.2
  2807.  
  2808.      java.io.DataInputStream in = new java.io.DataInputStream(System.in);
  2809.      String s = in.readLine();
  2810.  
  2811.  
  2812.      One way in JDK 1.1:
  2813.  
  2814.      java.io.BufferedReader in =
  2815.       new java.io.BufferedReader( new InputStreamReader(System.in));
  2816.  
  2817.      String s = in.readLine();
  2818.  
  2819.  
  2820.      Once you have the token in a String, it is easy to parse it into one of
  2821.      the other types, as shown earlier in the FAQ. Yes, it is bone-headed,
  2822.      as it makes the simplest case of keyboard I/O unnecessarily
  2823.      complicated. A bug was filed with Javasoft to record this problem, but
  2824.      don't count on this being fixed any time soon.
  2825.  
  2826.   2. (Sect. 7) Why do I have trouble with System.out.println()? Check the
  2827.      spelling. The last two characters are the letters "ell enn" not "one
  2828.      enn".
  2829.  
  2830.      The name of the method stands for "print line", since it prints a
  2831.      String and goes to the next line, rather than staying on the same line
  2832.      as System.out.print() does. Yes, the name is yet another Java naming
  2833.      inconsistency, since the input equivalent is readLine(), not readln().
  2834.  
  2835.   3. (Sect. 7) How do I write to the serial port on my PC using Java?
  2836.  
  2837.      [*] There is a platform-independent serial port API introduced in JDK
  2838.      1.2. You can download the documentation by registering with the Java
  2839.      Developer Connection (it's free, http://java.sun.com) and browsing
  2840.      http://java.sun.com/jdc/earlyAccess/communications.html.
  2841.  
  2842.      For systems prior to JDK 1.2, read on. At least two companies have
  2843.      written a library to drive the port. See
  2844.         o http://www.sc-systems.com has a library for Windows 95, WindowsNT,
  2845.           OS/2, Macintosh PPC, Solaris Sparc, Linux x86, FreeBSD x86, HP/UX
  2846.           PA-RISC, and possibly others too.
  2847.         o http://www.cd.com/portio
  2848.         o In addition, there is a Unix serial port utility available with
  2849.           source at http://jarvi.ezlink.com/rxtx/ It's free under the GPL,
  2850.           and works on Linux, Irix, Solaris, Windows 95, and NT.
  2851.  
  2852.      While not helpful to typical home users, there is an alternative
  2853.      portable COM port solution for Java 1.1 and even 1.0. Buy your COM
  2854.      ports in the form of "terminal servers". Using a COM port is now as
  2855.      easy as connecting to it with a Socket. Port parameters can be changed
  2856.      programatically using SNMP for most terminal servers (but this is never
  2857.      necessary when a modern modem or other fixed-rate equipment is
  2858.      attached). Any networked box can serve as a terminal server - even
  2859.      Win95 - with a simple native server application for that box, but
  2860.      buying an actual firmware based hardware box is much easier.
  2861.  
  2862.      Furthermore, your Win95 native applications can now share the COM ports
  2863.      (and any attached modems) via a Win95 product called "Dial-out IP" at
  2864.      http://www.tactical-sw.com/.
  2865.  
  2866.      If the port exists as a pathname in the filesystem, you can open it as
  2867.      a file and read/write. You can also print text this way by writing to
  2868.      "prn" or "lpt1" on a pc, and "/dev/something" on Unix. Writing a
  2869.      formfeed at the end of the file is essential on Windows 95. Here is
  2870.      some sample code:
  2871.  
  2872.      // class that opens the printer as a file
  2873.      // and writes "Hello World" to it
  2874.  
  2875.      import java.io.*;
  2876.      public class lpt {
  2877.          public static void main (String[] argv) {
  2878.              try {
  2879.                  FileOutputStream os = new FileOutputStream("LPT1");
  2880.                  //wrap stream in "friendly" PrintStream
  2881.                  PrintStream ps = new PrintStream(os);
  2882.  
  2883.                  //print text here
  2884.                  ps.println("Hello world!");
  2885.  
  2886.                  //form feed -- this is important
  2887.                  //Without the form feed, the text will simply sit
  2888.                  // in print buffer until something else gets printed.
  2889.                  ps.print("\f");
  2890.                  //flush buffer and close
  2891.                  ps.close();
  2892.              } catch (Exception e) {
  2893.                  System.out.println("Exception occurred: " + e);
  2894.              }
  2895.          }
  2896.      }
  2897.  
  2898.  
  2899.      If you wish to change the characteristics of the port (e.g. baud rate,
  2900.      parity, etc.), not just read/write data, Java currently offers no
  2901.      portable way to do this. You will need to use one of the packages
  2902.      mentioned above or some native code or a system command.
  2903.  
  2904.   4. (Sect. 7) How do I append to a file?
  2905.  
  2906.      [*] There are two ways. JDK 1.1 introduced new constructors for two of
  2907.      the output classes that allowed you to set a boolean flag:
  2908.  
  2909.      public FileWriter(String fileName, boolean append) throws IOException
  2910.      public FileOutputStream(String name, boolean append) throws IOException
  2911.  
  2912.  
  2913.      Another way is to do this:
  2914.  
  2915.      RandomAccessFile fd = new RandomAccessFile(file,"rw");
  2916.      fd.seek(fd.length());
  2917.  
  2918.  
  2919.      Then write using fd. Note that the latter method does not take
  2920.      advantage of the "append" mode present in many operating systems (such
  2921.      as all Unixes). Such a difference may make a difference with multiple
  2922.      processes or threads appending to the same output file. This can happen
  2923.      frequently, even if not intended by the programmer, e.g. with logfiles
  2924.      in multitasking environments. With the lack of file-locking mechanisms
  2925.      in Java the issue becomes even more significant.
  2926.  
  2927.   5. (Sect. 7) Is it possible to lock a file using Java ?
  2928.  
  2929.      [*] Java does not feature an API to lock a file or regions within a
  2930.      file. Code that needs to do this must take one of four approaches:
  2931.        1. Implement an advisory locking scheme using features that Java does
  2932.           have (synchronized methods). This allows you to lock files against
  2933.           use by other Java code running in the same JVM.
  2934.  
  2935.        2. Use an atomic operation like file "renameTo()" and have all
  2936.           processes (Java and non-Java) follow the same protocol: if the
  2937.           operation succeeds, you have the lock, and you change the file
  2938.           back to give up the lock. The FAQ previously recommended delete()
  2939.           or mkdir() as the primitive, but there has been a report that
  2940.           these operations are idempotent (can be repeated without error) in
  2941.           some JVMs. The suggestion of renameTo has been proven to work in
  2942.           practice. See http://www.camb.opengroup.org/~sanfilip/FileLock/
  2943.           for example locking class docs and source.
  2944.  
  2945.        3. Make calls to native code to issue the locking ioctls. This
  2946.           approach is not portable, but gives you a shot at having your
  2947.           locks respected by other programs using standard locking ioctls
  2948.           outside Java.
  2949.  
  2950.        4. Push the work to a central server. Since socket connection
  2951.           requests arrive in a single queue on the server, this can be used
  2952.           to serialize lock requests. There might be some merit in copying
  2953.           the NFS lockd protocol for a general approach. Rolling your own
  2954.           simple version for a specific application is pretty easy. A
  2955.           database would be better off locking records or fields, not byte
  2956.           offsets. In theory, the server socket approach would make it
  2957.           easier to perform automatic cleanup of a lock on abrupt VM process
  2958.           failure, e.g. by asking "are you still alive?" to the lock holder
  2959.           occasionally.
  2960.  
  2961.   6. (Sect. 7) How do I make the keyboard beep in Java?
  2962.  
  2963.      [*] In JDK 1.1, java.awt.Toolkit has the method beep(). It does not
  2964.      work on NT 4.0 (bug).
  2965.  
  2966.      System.out.print("\07");
  2967.      System.out.flush();
  2968.  
  2969.      should work, and works in JDK 1.0.2, too. That's the ASCII BEL
  2970.      character (Java doesn't support the C abstraction of '\a' for an alert
  2971.      character).
  2972.  
  2973.   7. (Sect. 7) How do I execute a command from Java? How do I do I/O
  2974.      redirection in Java using exec()?
  2975.  
  2976.      [*] See the answer to Question 17.7.
  2977.  
  2978.   8. (Sect. 7) How do you do file I/O from an applet?
  2979.  
  2980.      [*] For security reasons, untrusted applets accessed across the network
  2981.      are restricted from doing certain operations, including I/O. This
  2982.      prevents rogue applets from sending out your private data, or deleting
  2983.      it. A trusted (signed) applet can perform these operations (JDK 1.1
  2984.      on).
  2985.  
  2986.      The simplest approach for server-side I/O is to use the Linlyn class
  2987.      available from http://www.afu.com. This is free software under the GNU
  2988.      license, and uses FTP to move files between an applet and the server.
  2989.      It is suitable for low-volume non-critical use like keeping a
  2990.      high-score file. The Linlyn class has a very simple application
  2991.      programmer interface.
  2992.  
  2993.         o The following suggestion is for server-side input.
  2994.  
  2995.           You can read a file on the server if you can create a URL
  2996.           referencing the file. Then open a stream, then use any of the
  2997.           stream-based methods to read.
  2998.  
  2999.           This allows reading but not writing. It requires an http daemon
  3000.           running on the server, which will usually be the case.
  3001.  
  3002.           try{
  3003.              URL url = new URL("http://somewhere.com/test.txt");
  3004.            // or URL url = new URL( getDocumentBase(), filename);
  3005.              BufferedReader in = new BufferedReader(
  3006.                                    new InputStreamReader(
  3007.                                       url.openStream() ) );
  3008.              String s = in.readLine(); //read till you get a null line.
  3009.              } catch(MalformedURLException e){
  3010.                      System.out.println("URLException:"+e);
  3011.              } catch(IOException e){
  3012.                      System.out.println("IOException:"+e);
  3013.              }
  3014.           }
  3015.  
  3016.  
  3017.           You cannot write a file on the server this way.
  3018.         o The following suggestions are for server-side output.
  3019.  
  3020.           It absolutely requires the cooperation of the server to allow an
  3021.           applet to write a file to the server. This cooperation may take
  3022.           any of several forms:
  3023.              + FTP server
  3024.              + File server (webnfs or custom written)
  3025.              + Listening on a socket for data from applets
  3026.              + CGI script
  3027.              + Java RMI (remote method invocation)
  3028.              + JDBC process
  3029.  
  3030.           In particular:
  3031.              + FTP code. Use the Linlyn class mentioned above.
  3032.              + WebNFS. This is an evolution of the NFS (Network File System)
  3033.                to make file resources visible in browsers. More information
  3034.                at http://www.sun.com/webnfs
  3035.              + Open a socket back to the server and read/write the data.
  3036.                Have a process on the server that listens for socket
  3037.                connections from applets and does the requisite I/O. This
  3038.                does I/O on the server.
  3039.              + Or use a CGI script or servlet on the server to write when
  3040.                browsed.
  3041.         o The following suggestions are for client-side I/O.
  3042.  
  3043.           Use a trusted applet (see section on security). This will permit
  3044.           local I/O without any of the restraints mentioned above. In this
  3045.           regard, the appletviewer and many other browsers regard applets
  3046.           loaded from a local filesystem (rather than across the net) as
  3047.           being more trustworthy, and perhaps even allowed to do I/O.
  3048.         o Or use a browser that has a security policy that is configured to
  3049.           allow file I/O (such as Sun's appletviewer).
  3050.  
  3051.   9. (Sect. 7) I used a C program to write a binary file. When I instantiate
  3052.      a DataInputStream on the file in Java, and try to readInt, I do not get
  3053.      the correct numbers. Why is this?
  3054.  
  3055.      [*] Java does everything in network byte order (big-endian order), as
  3056.      do many computers including Motorola, and SPARC. The Intel x86 uses
  3057.      little-endian order in which the 4 bytes of an int are stored least
  3058.      significant first. Rearranging the bytes on the way in will get you the
  3059.      results you need. This is only necessary when the file was written by a
  3060.      non-Java program on a little-endian machine such as a PC.
  3061.  
  3062.      The following code will byte-swap little-endian integers into network
  3063.      standard order:
  3064.  
  3065.      public int swap(int i) {
  3066.          int byte0 = i & 0xff;
  3067.          int byte1 = (i>>8) & 0xff;
  3068.          int byte2 = (i>>16) & 0xff;
  3069.          int byte3 = (i>>24) & 0xff;
  3070.          // swap the byte order
  3071.          return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
  3072.      }
  3073.  
  3074.  
  3075.      Alternatively, the following code assembles bytes from a byte array
  3076.      that is in big-endian order (as used by Java) into an int:
  3077.  
  3078.      byte[] bytes = ... // whatever
  3079.      int start_index = ... // wherever
  3080.  
  3081.      int value = 0;
  3082.      for ( int i = start_index; i < start_index+4; ++i ) {
  3083.          value = ( value << 8 ) | ( bytes[i] & 0xFF );
  3084.      }
  3085.  
  3086.  
  3087.      If the bytes are in little-endian order, just change the "for"
  3088.  
  3089.      for ( int i = start_index+3; i >= start_index; --i )
  3090.  
  3091.  
  3092.      And this code will assemble a double that has been written in reverse
  3093.      byte order:
  3094.  
  3095.        byte[] gnol = new byte[8];
  3096.        stream.read(gnol);
  3097.  
  3098.        long l = (
  3099.                   ( (gnol[7] & 0xff) << 56) |
  3100.                   ( (gnol[6] & 0xff) << 48) |
  3101.                   ( (gnol[5] & 0xff) << 40) |
  3102.                   ( (gnol[4] & 0xff) << 32) |
  3103.                   ( (gnol[3] & 0xff) << 24) |
  3104.                   ( (gnol[2] & 0xff) << 16) |
  3105.                   ( (gnol[1] & 0xff) <<  8) |
  3106.                     (gnol[0] & 0xff)
  3107.                 );
  3108.  
  3109.        double d = Double.longBitsToDouble(l);
  3110.  
  3111.  
  3112.  10. (Sect. 7) How do I make I/O faster? My file copy program is slow.
  3113.  
  3114.      [*] This is the purpose of BufferedInputStream. It is a flaw in Java
  3115.      that buffered I/O is not the default, with a flag or different
  3116.      constructor to turn it off. I/O is the second worst designed package in
  3117.      Java, after the Date class. ,
  3118.  
  3119.  11. (Sect. 7) How do I do formatted I/O of floating point numbers?
  3120.  
  3121.      [*] Use the class java.text.NumberFormat.
  3122.  
  3123.      Or use http://www.newbie.net/sharky/lava/. Or do a web search for
  3124.      hbprintf. Or use http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html
  3125.      for the HTML with the javadoc info. The actual file is called
  3126.      http://www.apl.jhu.edu/~hall/java/CoreJava-Format.java. However, you
  3127.      must rename the file to Format.java for it to compile. Also, one
  3128.      version of this had a bug: When you try to format a true 0 you go into
  3129.      an infinite loop (need to test d in exp_format).
  3130.  
  3131.      Although many utilities claim to handle all varieties of C's printf, as
  3132.      far as has been found, this is the only one to correctly handle the
  3133.      equivalent of %e in printf.
  3134.  
  3135.  12. (Sect. 7) How do I read numbers in exponential format in Java?
  3136.  
  3137.      [*] The program below (written by Steve Chapel) uses StreamTokenizer to
  3138.      read data from the standard input and recognizes doubles in exponential
  3139.      format (e.g. -1.23e-45).
  3140.  
  3141.      import java.io.*;
  3142.  
  3143.      public class ReadExponential {
  3144.          public static void main(String argv[]) {
  3145.              DataInputStream in = new DataInputStream(System.in);
  3146.              StreamTokenizer st = new StreamTokenizer(in);
  3147.              try {
  3148.                  while (st.nextToken() != StreamTokenizer.TT_EOF) {
  3149.                      switch (st.ttype) {
  3150.  
  3151.         case StreamTokenizer.TT_NUMBER:
  3152.                   double num = st.nval;
  3153.                   int exp = 0;
  3154.                   st.ordinaryChars('\0', ' ');
  3155.                   st.nextToken();
  3156.                   st.whitespaceChars('\0', ' ');
  3157.                   if (st.ttype == StreamTokenizer.TT_WORD &&
  3158.                       Character.toUpperCase(st.sval.charAt(0)) == 'E') {
  3159.                       try {
  3160.                          exp = Integer.parseInt(st.sval.substring(1));
  3161.                       } catch (NumberFormatException e) {
  3162.                          st.pushBack();
  3163.                       }
  3164.                   } else if (st.ttype < 0 || st.ttype > ' ')
  3165.                       st.pushBack();
  3166.                   System.out.println("Num " + num * Math.pow(10, exp));
  3167.                   break;
  3168.          case StreamTokenizer.TT_WORD:
  3169.                   System.out.println("Word " + st.sval);
  3170.                   break;
  3171.          default:
  3172.                   System.out.println("Char '" + (char) st.ttype + "'");
  3173.                   break;
  3174.               } // end switch
  3175.           }  // end while
  3176.         } catch (IOException e) {
  3177.           System.out.println("IOException: " + e);
  3178.         }
  3179.       } // end main
  3180.      }
  3181.  
  3182.  
  3183.  13. (Sect. 7) I'm trying to read in a character from a text file using the
  3184.      DataInputStream's readChar() method. However, when I print it out, I
  3185.      get ?'s.
  3186.  
  3187.      [*] Remember that Java characters are 16-bit Unicode characters, while
  3188.      many hosts systems store characters as 8-bit ASCII characters.
  3189.      Therefore, to read individual chacters from a text file, you need to
  3190.      ensure the proper conversion. The proper way to do this is to use an
  3191.      InputStreamReader, which converts from 8 to 16 bit streams:
  3192.  
  3193.      FileInputStream fis = new FileInputStream("myfile.txt");
  3194.      InputStreamReader isr = new InputStreamReader(fis);
  3195.      char c3 = (char) isr.read();
  3196.  
  3197.      The less-favored way (because it is not so portable, as the encodings
  3198.      translation is not done) is just to read a byte and cast it into a
  3199.      character:
  3200.  
  3201.      FileInputStream fis = new FileInputStream("myfile.txt");
  3202.      DataInputStream dis = new DataInputStream(fis);
  3203.      char c1 = (char) dis.readByte();
  3204.  
  3205.  
  3206.  14. (Sect. 7) How do I delete a directory in Java?
  3207.  
  3208.      [*] JDK 1.0 did not support directory removal. JDK 1.1 supports
  3209.      directory removal with the method:
  3210.           public boolean delete() in class java.io.File
  3211.  
  3212.      Make sure you don't have any open streams in the directory you're
  3213.      trying to remove. Do a close() on all streams, even if the underlying
  3214.      file is gone.
  3215.  
  3216.  15. (Sect. 7) How do I tell how much disk space is free in Java?
  3217.  
  3218.      [*] There currently aren't any good Java APIs for system introspection.
  3219.      There is no Java way to control processes, or look at system resources.
  3220.      You can use Runtime.getRuntime().exec() to do "df" on unix or "dir" on
  3221.      Windows right now.
  3222.  
  3223.      Alternatively, check out JConfig:
  3224.      http://www.tolstoy.com/samizdat/jconfig.html
  3225.      JConfig is a cross-platform library that fills in many of the gaps in
  3226.      the core Java API, and makes it possible to work with files, processes,
  3227.      file types, video monitors, etc. in a much more Windows- and
  3228.      Mac-friendly manner.
  3229.  
  3230.  16. (Sect. 7) How do I get a directory listing of the root directory C:\ on
  3231.      a PC?
  3232.  
  3233.      [*] The obvious approach of calling File.list("C:\"); does not work.
  3234.      There are two reasons why this fails. First, slash is an escape
  3235.      character in Java, so if you want a literal slash, you have to repeat
  3236.      it. Second, you need to give the name of the directory, i.e. dot.
  3237.      Putting this together, either of the following calls will work
  3238.  
  3239.      File.list("C:\\.");
  3240.  
  3241.  
  3242.      or
  3243.  
  3244.      File.list("C:/.");
  3245.  
  3246.  
  3247.      Note: a file separator of "/" works just as well as "\" in most Windows
  3248.      programs and library calls. It is an artifact of DOS's origin's as a
  3249.      ripped-off port of CP/M. CP/M didn't have directories, so it didn't use
  3250.      pathname separators. The forward slash "/" was already used for giving
  3251.      options to CP/M commands, so "\" was pressed into service as the
  3252.      pathname separator, but the shell understood "/" for compatibility with
  3253.      other OS's. See also JConfig in Q6.15.
  3254.  
  3255.  17. (Sect. 7) What is the difference between the various ZIP formats: ZIP,
  3256.      GZIP, and PKZIP?
  3257.  
  3258.      [*] Zip is an archive file format, popularized on PCs, that contains
  3259.      multiple compressed files.
  3260.      GZIP comes from Gnu. It is essentially a one file subset of the Zip
  3261.      format. You can't put a whole directory into a GZIP archive, just a
  3262.      single file.
  3263.      PKZIP is a set of commercially available programs that create Zip
  3264.      files. All three use the deflate compression format, which is based on
  3265.      the LZ77 algorithm. This compression is also used by the ZLIB library
  3266.      and hence the PNG graphics file format (which uses ZLIB). PNG -
  3267.      Portable Network Graphics - provides a patent-free replacement for GIF
  3268.      and TIFF. If you save a GIF, don't forget to pay the royalty to Unisys
  3269.      - see Unisys's web page at http://www.unisys.com/LeadStory/lzwfaq.html.
  3270.      That patent is why GIFs should not be used.
  3271.  
  3272.      The PNG format is specified in RFCs 1950, 1951, and 1952, and is
  3273.      unencumbered by licenses or patents.
  3274.  
  3275.      An alternative compression technology, LZW compression, is encumbered
  3276.      by Unisys's patent. LZW is used in GIF files and by the Unix compress
  3277.      command. Luckily, as well as being free from patent restrictions, LZ77
  3278.      also gives better compression than LZW. LZW is the initial letters of
  3279.      the last names of the three computer scientists who developed the
  3280.      algorithm (Lempel, Ziv, Welch).
  3281.  
  3282.      The basic classes (all in java.util.zip) that read LZ77 Zip format are
  3283.      Deflater and Inflater. These are used by the stream classes
  3284.      DeflaterOutputStream and InflaterInputStream. The java.util.zip classes
  3285.      GZIPInputStream and ZipInputStream inherit from InflaterInputStream.
  3286.  
  3287.      PKZIP is a commercial program for DOS, Windows, and OS/2, sold by
  3288.      PKWARE Their FAQ, at http://www.pkware.com/zipgfaq.html, specifically
  3289.      says
  3290.           "Because PKWARE has dedicated the .ZIP file format to the public
  3291.           domain, it is possible for other people to write programs which
  3292.           can read .ZIP files. NOTE THAT THE PKZIP, PKUNZIP, PKSFX PROGRAMS
  3293.           AND THEIR ASSOCIATED SOURCE CODE AND SUPPORT PROGRAMS ARE THE
  3294.           EXCLUSIVE PROPERTY OF PKWARE INC. AND ARE NOT PUBLIC DOMAIN
  3295.           SOFTWARE PROGRAMS.
  3296.  
  3297.      The "other people" PKZIP's FAQ refers to is the InfoZIP project, a
  3298.      group of public-minded programmers spread over the world producing free
  3299.      software that works on most ANSI C compilers and platforms. See
  3300.           http://www.cdrom.com/pub/infozip/.
  3301.  
  3302.      Jar files are in ZIP format, but are not as complete as a full
  3303.      filesystem archive format since file permissions are not saved. Some
  3304.      versions of WinZip are known to be inadequate for processing the full
  3305.      PKZIP format. Use InfoZIP instead.
  3306.  
  3307.  18. (Sect. 7) How can I use characters other than ASCII in Java?
  3308.  
  3309.      [*] Search for the article titled "Adding Fonts to the Java Runtime" at
  3310.      http://java.sun.com/.
  3311.  
  3312.      The article explains how to add fonts to Sun's JDK, using the
  3313.      font.properties file. [If anyone has summarised the information, please
  3314.      send it in].
  3315.  
  3316.  19. (Sect. 7) I did a read from a Buffered stream, and I got fewer bytes
  3317.      than I specified.
  3318.  
  3319.      [*] This is the way that BufferedInputStream works up to and including
  3320.      the current release. The behavior is so unintuitive that it really
  3321.      represents a bug. Javasoft has "resolved" the bug by writing the
  3322.      comments in the program so that the behavior is not disallowed.
  3323.  
  3324.      When you instantiate a buffered input stream, you can specify the size
  3325.      of buffer it should use. Let's call this the internal buffer. When you
  3326.      call read() you can say how many bytes to read. Let's call this the
  3327.      request. If the request is smaller than the internal buffer and not a
  3328.      multiple of the internal buffer, then the last read returns only the
  3329.      odd bytes left in the internal buffer! The more reasonable and
  3330.      intuitive behavior would be for the internal buffer to be refilled, so
  3331.      that the whole request can be granted.
  3332.  
  3333.      For example, if you create a BufferedInputStream with an internal
  3334.      buffer of 1000 bytes, and try to read 512 byte chunks, your first read
  3335.      will return 512 bytes, but your second read will only return
  3336.      (1000-512), or 488, bytes. (Assuming that the file has at least that
  3337.      many bytes in it). The following code illustrates the problem.
  3338.  
  3339.      // troubleshooting by Tov Are Jacobsen
  3340.      import java.io.*;
  3341.      class filebug {
  3342.          public static void main(String args[])
  3343.                        throws FileNotFoundException, IOException  {
  3344.          BufferedInputStream bis =
  3345.             new BufferedInputStream(
  3346.             new FileInputStream("test.txt"), 1000 );
  3347.          byte[] buf = new byte[2000];
  3348.          int numread;
  3349.          System.out.println( "Available: "+bis.available() );
  3350.          while (true) {
  3351.              numread = bis.read(buf,0,512);
  3352.              if (numread<0) break;
  3353.              System.out.println( "got "+numread
  3354.                                 +", avail:"+ bis.available());
  3355.          }
  3356.        }
  3357.      }
  3358.  
  3359.  
  3360.      Of course, a valid reason for getting less than you asked for is that
  3361.      you asked for more data than is actually available in the Stream, e.g.
  3362.      you requested 512 bytes from a file that only contains 40 bytes. In
  3363.      general, there are no guarantees about how much data is returned for a
  3364.      given buffered input stream read request. To avoid this problem, push a
  3365.      DataInputStream on top of your buffered stream. Then you can call
  3366.      readFully(), which will do what you want.
  3367.  
  3368.      A similar "got less than I asked for" occurs when reading a socket.
  3369.      Network protocols frequently packetize data and send it across in
  3370.      bursts. Nothing is lost of course, and you are always told how many
  3371.      bytes you actually got. You will get the remaining bytes on a
  3372.      subsequent read. This happens regardless of the language used. Be sure
  3373.      to check the "amount of data returned" when using the read(byte[], int,
  3374.      int) method of BufferedInputStream, or when reading from a socket.
  3375.  
  3376.      Another problem with java.io.InputStream.read(byte[], int, int) is that
  3377.      it catches and ignores IOExceptions. Instead, these exceptions should
  3378.      be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com,
  3379.      has a version to do this at http://www.acme.com/jef/.
  3380.  
  3381.  20. (Sect. 7) How do I redirect the System.err stream to a file?
  3382.  
  3383.      [*] You cannot assign a new FileOutputStream to System.err, as it is
  3384.      final. Instead use the System.setErr() library call, like this:
  3385.  
  3386.      FileOutputStream err = new FileOutputStream("stderr.log");
  3387.      PrintStream errPrintStream = new PrintStream(err);
  3388.      System.setErr(errPrintStream);
  3389.  
  3390.  
  3391.      This was introduced with JDK 1.1. There is also a corresponding setIn()
  3392.      for redirecting standard in, and a setOut() for standard out.
  3393.  
  3394.      Note that you will get a compiler warning about a deprecated construct
  3395.      when you do this. PrintStreams are deprecated in favor of PrintWriters,
  3396.      which handle Unicode properly. The PrintStream is marked as deprecated
  3397.      by marking all its constructors as deprecated. There is no way to
  3398.      create the PrintStream needed to redirect System.err or System.out
  3399.      without triggering the deprecated warning.
  3400.  
  3401.                        -------------------------------
  3402.  
  3403. 8. Core Libraries
  3404.  
  3405.   1. (Sect. 8) I can't seem to change the value of an Integer object once
  3406.      created.
  3407.  
  3408.      [*] Correct. Integer (Float, Double, etc) are intended as an object
  3409.      wrapper for a specific value of a number, not as a general-purpose way
  3410.      of shipping a primitive variable around as an Object. If you need that
  3411.      it's easy enough to create: class General { public int i; }
  3412.  
  3413.   2. (Sect. 8) How do I print from a Java program?
  3414.  
  3415.      [*] Use the Toolkit.getPrintJob() method
  3416.  
  3417.      Component c = this.getParent();
  3418.      while (c!=null && !(c instanceof Frame))
  3419.          c=c.getParent();
  3420.  
  3421.      PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
  3422.      Graphics pg = pj.getGraphics();
  3423.      printAll(pg);
  3424.      pg.dispose();
  3425.      pj.end();
  3426.  
  3427.  
  3428.      This feature was introduced with JDK 1.1. A common place to put this is
  3429.      in the code that handles a button press. Printing from an untrusted
  3430.      applet is subject to a check from the SecurityManager.
  3431.  
  3432.      The JDK 1.1 printing API is more a screen hardcopy facility than a full
  3433.      blown publishing and illustration hardcopy API. JDK 1.2 offers a more
  3434.      full-featured printing API.
  3435.  
  3436.      If you simply want to print text, then write it to a file and print the
  3437.      file. Or open a filename that corresponds to the printer. On Windows,
  3438.      that is "LPT1" and the code looks like:
  3439.  
  3440.      try {
  3441.          FileOutputStream fos = new FileOutputStream("LPT1");
  3442.          PrintStream ps = new PrintStream(fos);
  3443.                  ps.print("Your string goes here");
  3444.                  ps.print("\f");
  3445.                  ps.close();
  3446.      } catch (Exception e) {
  3447.          System.out.println("Exception occurred: " + e);
  3448.      }
  3449.  
  3450.  
  3451.      The final formfeed is needed by windows to start the printjob.
  3452.  
  3453.   3. (Sect. 8) What are the properties that can be used in a PrintJob?
  3454.  
  3455.      [*] The properties are
  3456.         o awt.print.destination - can be "printer" or "file"
  3457.         o awt.print.printer - printer name
  3458.         o awt.print.fileName - name of the file to print
  3459.         o awt.print.options - options to pass to the print command
  3460.         o awt.print.orientation - can be "portrait" or "landscape"
  3461.         o awt.print.paperSize - can be "letter","legal","executive" or "a4"
  3462.      The defaults are destination=printer, orientation=portrait,
  3463.      paperSize=letter, and numCopies=1.
  3464.  
  3465.      You can search for info like this by joining the Java Developer
  3466.      Connection (it's free) at http://java.sun.com/jdc.
  3467.  
  3468.      and doing a search for "PrintJob".
  3469.  
  3470.   4. (Sect. 8) Is there any package in Java to handle HTML?
  3471.  
  3472.      [*] See the answer to Question 13.14.
  3473.  
  3474.   5. (Sect. 8) Why don't Dialogs work the way I want them to?
  3475.  
  3476.      [*] Modal dialogs (dialog windows that stay up until you click on them)
  3477.      are buggy in many browsers and in the 1.0.2 JDK. One bug is that the
  3478.      dialog is not necessarily put on top when it is displayed. Most of the
  3479.      modal dialog bugs are fixed in JDK 1.1.
  3480.  
  3481.   6. (Sect. 8) Where can I find information about the sun.* classes in the
  3482.      JDK?
  3483.  
  3484.      [*] You're not supposed to. Those classes are only to support functions
  3485.      in the java.* hierarchy. They are not part of the API, and won't be
  3486.      present in Java systems from non-Sun vendors. Some people have
  3487.      reverse-engineered the code and published an API for these classes but
  3488.      you use it at your own risk, and it may change without warning.
  3489.  
  3490.      Worst of all, those programs will not have the portability of true Java
  3491.      but will only run on Sun JDKs. For the same reason you shouldn't use
  3492.      classes outside the java.* packages when using JDKs from other vendors.
  3493.  
  3494.      If you still insist on going ahead, check these URLs:
  3495.      http://java.sun.com/products/api-overview/index.html
  3496.      http://www.parmly.luc.edu/javaudio/
  3497.      http://www.users.interport.net/~mash/javamidi.html
  3498.  
  3499.   7. (Sect. 8) How do you read environment variables from with a Java
  3500.      program?
  3501.  
  3502.      [*] Environment variables are not used in Java, as they are not
  3503.      platform-portable. The Mac doesn't have environment variables, for
  3504.      example. A Windows 95 application not started from a DOS window does
  3505.      not have environment variables. Use properties instead. It was a design
  3506.      error in JDK 1.0 that programmers had to set the CLASSPATH environment
  3507.      variable. This should have been set in a property file. JDK 1.1 removes
  3508.      the need to set the CLASSPATH environment variable until you start
  3509.      creating packages of your own.
  3510.  
  3511.      Create your own properties file (see java.util.Properties) or specify
  3512.      them with the -D option when you invoke the interpreter or JRE.
  3513.      Additionally, on some systems you can set a property from the command
  3514.      invocation line like this:
  3515.  
  3516.      java -Dfoo=$foo MyClass (Unix)
  3517.  
  3518.      or
  3519.  
  3520.      java -Dfoo=%foo% MyClass (Win95/NT)
  3521.  
  3522.      This sets the "foo" property to the value of the environment variable
  3523.      foo, and makes it available in the System properties. Make sure you do
  3524.      not leave any spaces after the -D or around the = sign. Inside the
  3525.      program you get the value with:
  3526.  
  3527.      String env = System.getProperty("foo");
  3528.  
  3529.      More simply, just put the environment variable on the command line and
  3530.      read it as arg[0].
  3531.  
  3532.      java MyClass %FOO% ; Win32
  3533.          java MyClass $FOO ; Unix
  3534.  
  3535.  
  3536.      Finally, you could execute a Runtime process to get the environment
  3537.      variables if you are on a platform that has them. This is a poor
  3538.      approach as it builds platform-specific knowledge into the program. See
  3539.      Question 10.6 for more details. On Unix, the command that prints
  3540.      environment variables is "/usr/bin/env". On Windows95, it is "set"
  3541.  
  3542.   8. (Sect. 8) How do I get Java talking to a Microsoft Access database?
  3543.  
  3544.      [*] Use the JDBC-ODBC bridge. It is not especially challenging to set
  3545.      up, but it does require painstaking attention to detail. There is a
  3546.      step-by-step example in the van der Linden text "Just Java 1.1"
  3547.      mentioned in the ponsorship section of this document.
  3548.  
  3549.      Note that the Microsoft version of the Java kit does not support
  3550.      JDBC-ODBC access because it uses a non-standard native code interface.
  3551.      The JDBC FAQ can be found at
  3552.      http://java.sun.com/products/jdbc/jdbc-frequent.html
  3553.  
  3554.   9. (Sect. 8) I can't seem to change the current working directory.
  3555.  
  3556.      [*] Correct. This missing functionality is an oversight that we hope
  3557.      will be corrected in the future. The bug id is 4156278, please feel
  3558.      free to join the JDC, and vote to have this (or any other) fixed.
  3559.      Changing the user.dir property merely changes the text property, not
  3560.      the underlying reality that it is supposed to reflect.
  3561.  
  3562.      There are several workarounds.
  3563.         o Run your java app from a .bat or .sh file and do the "cd" in that
  3564.           (before you run your java app), assuming that all the external
  3565.           processes you need to exec can be run from the same directory.
  3566.         o Do: exec("cd /home/wherever; externalApp.exe") on unix, (there
  3567.           doesn't seem to be an equivalent on NT).
  3568.         o Instead of running the .exe directly, run (or write on the fly) a
  3569.           .bat or .sh file that does the cd and then runs the .exe for you
  3570.           (this could well create trouble with getting back the correct
  3571.           return status)
  3572.  
  3573.  10. (Sect. 8) How do I create a Vector of ints?
  3574.  
  3575.      [*] ints are primitive types and hence can't be stored by the Vector
  3576.      class, which stores objects. You'll need to wrap the ints. Try this:
  3577.  
  3578.      int i =7;
  3579.      Vector holdsInts = new Vector(5,1);
  3580.  
  3581.      holdsInts.addElement(new Integer(i));
  3582.      int j = ((Integer)holdsInts.elementAt(0)).intValue();
  3583.  
  3584.  
  3585.  11. (Sect. 8) I have several worker threads. I want my main thread to wait
  3586.      for any of them to complete, and take action as soon as any of them
  3587.      completes. I don't know which will complete soonest, so I can't just
  3588.      call Thread.join on that one. How do I do it?
  3589.  
  3590.      [*] You need to use the wait/notify mechanism to allow any of the
  3591.      worker threads to wake up your main thread when the worker has
  3592.      completed.
  3593.  
  3594.  12. (Sect. 8) How do I get random numbers?
  3595.  
  3596.      [*] If you just need a quick random double between 0.0 and just less
  3597.      than 1.0
  3598.  
  3599.      double myrandom = Math.random(); // [0,1)
  3600.  
  3601.  
  3602.      The notation "[0,1)" is common math notation for "zero to .9999999 etc"
  3603.      The Sun documents say this returns 0.0 to 1.0, but inspection of the
  3604.      source shows they are wrong. However, due to the inherent inaccuracies
  3605.      of floating point arithmetic, multiplying N by 0.999999 etc can result
  3606.      in an answer of N, not N * .999999. So watch out when N is big.
  3607.  
  3608.      Where things get even trickier is in the case where you want an int
  3609.      within a certain range, say 1 to 6 to simulate the throw of a die or 1
  3610.      to 52 to represent a playing card. Class Random has a nextInt method
  3611.      that will return any integer:
  3612.  
  3613.      import java.util.Random;
  3614.      Random r = new Random();
  3615.      int i = r.nextInt();
  3616.  
  3617.  
  3618.      However, that has an (almost) 50% chance of being negative, and it
  3619.      doesn't come from the right range. So you just take the abs() value and
  3620.      then mod it into the right range:
  3621.  
  3622.      int dice_throw = 1 + Math.abs(i) % 6;
  3623.  
  3624.  
  3625.      Except, the abs() method fails gracelessly in the presence of the
  3626.      Integer.MIN_VALUE (it returns the same, negative, result!). So it is
  3627.      better to AND to get the non-negative value: In general, to get a
  3628.      random int between high and low limits (inclusive):
  3629.  
  3630.      java.util.Random r = new java.util.Random();
  3631.      int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;
  3632.  
  3633.  
  3634.      The sentence above states "(almost) 50% chance" because there is one
  3635.      more value in the negative integers than in the positive integers in
  3636.      two's complement arithmetic as used by Java. For most purposes, the
  3637.      bias introduced will be insignificant, but we "and" the nextInt() to
  3638.      convert it to zero. Sure, it's unlikely to occur, but you don't want
  3639.      the reactor going critical just because you missed this case while
  3640.      testing.
  3641.  
  3642.      A worse problem is that with the algorithm used, the low order bits are
  3643.      significantly less random than the higher order bits. And the low order
  3644.      bits are precisely the ones you get when you do a (mod 2^n) operation.
  3645.  
  3646.  13. (Sect. 8) What does "deprecated" mean? I got this in a compiler error
  3647.      message.
  3648.  
  3649.      [*] The compiler will flag a now-obsolete API as "deprecated". The word
  3650.      means "officially disapproved of". Compile again with the
  3651.      "-deprecation" option to see what is deprecated. In almost all cases,
  3652.      the old API has been replaced by a new one. Update your code to use the
  3653.      new one.
  3654.  
  3655.      An example of using a deprecated API is calling component.size(). That
  3656.      has been replaced by component.getSize().
  3657.  
  3658.  14. (Sect. 8) Where/why should I use the Enumeration interface?
  3659.  
  3660.      [*] It's a very convenient way to step through some of the library data
  3661.      structures, such as HashTable, Vector, and ZipFile. It is thread safe.
  3662.      If you're looking at an element in one thread while another thread is
  3663.      trying to delete it, it won't half vanish.
  3664.  
  3665.      Here's how you might look at every file in a ZIP file:
  3666.  
  3667.      ZipFile z = new ZipFile("foo.zip");
  3668.      Enumeration e = null;
  3669.      for (e=z.entries(); e.hasMoreElements(); ) {
  3670.         ZipEntry ze = (ZipEntry)e.nextElement();
  3671.         System.out.println("got " + ze.getName() );
  3672.      }
  3673.  
  3674.  
  3675.      And here's how you might look at all the tokens in a String:
  3676.  
  3677.      StringTokenizer tokens =
  3678.          new StringTokenizer (SomeArbitraryString, "\n", false);
  3679.  
  3680.      Enumeration enum = tokens.elements();
  3681.      while enum.hasMoreElements()
  3682.          System.out.println(enum.nextElement());
  3683.  
  3684.      You should look for opportunities in your own data structures to
  3685.      implement Enumeration anywhere where the structure has repeated
  3686.      elements.
  3687.  
  3688.  15. (Sect. 8) Which version of WinZip is compatible with java.util.zip?
  3689.  
  3690.      [*] You need WinZip version 6.2 or later. Version 6.1 or earlier is not
  3691.      good enough. WinZip can be downloaded from
  3692.      http://www.winzip.com/download.cgi. The pkzip software works fine.
  3693.      Infozip is better than WinZip because it lacks the winzip "feature" of
  3694.      failing to recreate directories unless given a special option. Use
  3695.      Infozip.
  3696.  
  3697.  16. (Sect. 8) How can Java access other fonts on my system?
  3698.  
  3699.      [*] You do it by editing the fontnames in the font.properties file in
  3700.      the lib directory of your JDK release. Watch out for program
  3701.      portability when you do this.
  3702.  
  3703.      For more details, check the website
  3704.      http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft site
  3705.      at http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
  3706.      They have lots of information on this.
  3707.  
  3708.  17. (Sect. 8) How can I trap Control-C in Java?
  3709.  
  3710.      [*] Control-C is used on some OS's to break into a running program
  3711.      interactively and terminate it. On Unix Control-C is sent to the
  3712.      process as a signal. If a C program declares a handler for that signal,
  3713.      the program will be able to continue even if Control-C is sent to it.
  3714.      Control-C is not a Java concept, and there is no way to do this in pure
  3715.      Java. You can write the signal handler in C however, and impose the
  3716.      handler by calling the C routine through the Java Native Interface.
  3717.  
  3718.                        -------------------------------
  3719.  
  3720. 9. Dates and Times
  3721.  
  3722.      Credit to Paul Hill who completely rewrote this section, and to
  3723.      the programmers at IBM who implemented much of the Java Date code,
  3724.      and reviewed this section of the FAQ for accuracy.
  3725.  
  3726.                                java.util.Date
  3727.  
  3728.   1. (Sect. 9) Is Java "Year 2000"-compliant?
  3729.  
  3730.      [*] Java is Y2K compliant in release JDK 1.1.6 and later. See
  3731.      http://www.sun.com/y2000/cpl.html. Prior to this release there were
  3732.      certain corner case bugs that had to be fixed.
  3733.  
  3734.      The Date class, as you can see from the discussion, contains more than
  3735.      enough resolution to represent dates in this century and the next and
  3736.      the last. The SimpleDateFormat when parsing a 2 digit year could cause
  3737.      problems; see discussion below.
  3738.  
  3739.   2. (Sect. 9) What happen to java.util.Date between JDK 1.0 and JDK 1.1?
  3740.  
  3741.      [*] In JDK 1.1 the java.util.Date class was split to provide better
  3742.      support for timezones, and internationalization.
  3743.  
  3744.      The classes specifially related to dates are summarized below:
  3745.  
  3746.             1. The class Date represents a specific instant in time,
  3747.                with millisecond precision.
  3748.             2. The class TimeZone is an abstract class that represents
  3749.                a time zone offset, and also figures out daylight
  3750.                savings time adjustment.
  3751.             3. The class SimpleTimeZone is the only concrete subclass
  3752.                of TimeZone in the JDK.  It is what defines an ordinary
  3753.                timezone with a simple daylight savings and daylight
  3754.                savings time period.
  3755.             4. The class Calendar is an abstract class for converting
  3756.                between a Date object and a set of integer fields such
  3757.                as year, month, day, and hour.
  3758.             5. The class GregorianCalendar is the only concrete
  3759.                subclass of Calendar in the JDK. It does the
  3760.                Date-to-fields conversions for the calendar system in
  3761.                common use.
  3762.             6. The class DateFormat is an abstract class that lets you
  3763.                convert a Date to a printable string with fields in the
  3764.                way you want (e.g. dd/mm/yy or dd.MMM.yyyy).
  3765.             7. The class SimpleDateFormat is the only concrete subclass
  3766.                of DateFormat in the JDK. It takes a format string and
  3767.                either parses a string to produce a date or takes  a
  3768.                date and produces a string.
  3769.  
  3770.      At least one critic has used the term "baroque" when describing the
  3771.      complexities of the Java date related classes, but other critics would
  3772.      spell that "broke". The good news is that as of JDK 1.2 all of the
  3773.      common problems have been corrected and many of the bugs were corrected
  3774.      in 1.1.4 and 1.1.6. Even in 1.1.1, you can avoid most of the most
  3775.      annoying bugs by always keeping in mind which timezone each class is
  3776.      using.
  3777.  
  3778.   3. (Sect. 9) Exactly what is a java.util.Date?
  3779.  
  3780.      [*] A java.util.Date stores a moment in time as a long integer
  3781.      representing the number of milliseconds since 00:00:00 Jan 1, 1970 UTC
  3782.      (Coordinated Universal Time). This zero moment is known as the "Epoch".
  3783.      This is the same Epoch as is used on Unix systems. Dates earlier than
  3784.      the Epoch are represented as negative numbers, counting away from
  3785.      1/1/1970.
  3786.  
  3787.      The scheme is sufficient to represent dates from 292,269,053 B.C. to
  3788.      292,272,993 A.D. (64 bits covers -9,223,372,036,854,775,808 to
  3789.      +9,223,372,036,854,775,807 milliseconds. But note that prior to JDK
  3790.      1.2, a GregorianCalendar will not accept values earlier than 4716 B.C.
  3791.  
  3792.      A java.util.Date is the light-weight object intended to just hold a
  3793.      millisecond value. It is used to hold, communicate and store a moment
  3794.      in time. Other tasks like creating a formated string, or calculating
  3795.      dates are best done using other classes.
  3796.  
  3797.   4. (Sect. 9) Does a java.util.Date really represent the true UTC?
  3798.  
  3799.      [*] No, but it is close enough for most human time-keeping purposes. On
  3800.      most computers, it only represents the time since the epoch as
  3801.      converted from the value on the underlying hardware. If you have
  3802.      hardware that is synchronized with an atomic clock your time is UTC;
  3803.      most hardware assumes a day is 24 hours long, but there have been more
  3804.      than 20 leap seconds added to UTC, since the first one was added in
  3805.      1972.
  3806.  
  3807.   5. (Sect. 9) How do I create a Date object that represents the current
  3808.      time?
  3809.  
  3810.      [*] The default value of a date object is the current time, so the
  3811.      following code creates a date object that contains the current time.
  3812.  
  3813.      Date now = new Date();
  3814.  
  3815.   6. (Sect. 9) I want to create a string that represents a date in a format
  3816.      other than what is returned by java.util.Date.toString() do I have to
  3817.      use a Calendar?
  3818.  
  3819.      [*] No. Instead of creating a Calendar and pulling out all of the
  3820.      appropriate fields and making a string, you could use
  3821.      SimpleDateFormat.format() to create a string.
  3822.  
  3823.   7. (Sect. 9) Why are all the methods in java.util.Date deprecated?
  3824.  
  3825.      [*] Mostly because the original java.util.Date was not completely aware
  3826.      of the timezone and "not amenable to internationalization". To make it
  3827.      timezone aware and internationalizable would have required adding some
  3828.      of the functionality which can now be seen in java.util.Calendar and
  3829.      some of the functionality in java.util.DateFormat. If you find the
  3830.      combination all of the date related classes complex, just be glad they
  3831.      were separated into different classes.
  3832.  
  3833.   8. (Sect. 9) I really don't need a internationalizable, timezone aware,
  3834.      extra flexible formating set of date classes, is there anything else
  3835.      with which I can use that stores a time and allows me to do some date
  3836.      calculations?
  3837.  
  3838.      [*]You could consider using the BigDate class written by Roedy Green,
  3839.      and available in his very informative glossary (search for BigDate). If
  3840.      you want to store the result in a database as a Date or TimeStamp, you
  3841.      should read the section below on java.sql.Date.
  3842.  
  3843.   9. (Sect. 9) Since the Date( String ) constructor is deprecated what do I
  3844.      use instead?
  3845.  
  3846.      [*] The best choice is to use SimpleDateFormat.parse() to create a
  3847.      java.util.Date object.
  3848.  
  3849.      The Date constructor that accepts a string calls Date.parse( String ).
  3850.      The Date.parse() function had its own rules for converting 2 digit
  3851.      years (it used a 1980 pivot date) and other limitiations which makes it
  3852.      of limited value. Other "features" of Date.parse() that are not
  3853.      supported in SimpleDate have not been missed by many developers.
  3854.  
  3855.  10. (Sect. 9) Since Date(int year, int month, int date) and related
  3856.      constructors are deprecated what do I use instead?
  3857.  
  3858.      [*] The constructor GregorianCalendar(int year, int month, int date) is
  3859.      the newer replacement. Other choices are the Calendar.set( year, month,
  3860.      day ) method. Note that the year in the GregorianCalendar starts at 1
  3861.      A.D., not at 1901 like the old Date constructor.
  3862.  
  3863.  
  3864.                                 java.util.TimeZone
  3865.  
  3866.  11. (Sect. 9) How can I see if my JVM is using the right timezone?
  3867.  
  3868.      [*] The following codes displays the ID of the current default
  3869.      timezone.
  3870.  
  3871.        System.out.println( TimeZone.getDefault().getID() );
  3872.  
  3873.  12. (Sect. 9) The value of TimeZone.getDefault is not what I expected. What
  3874.      is the problem?
  3875.  
  3876.      [*] The value of the default timezone is based on the value of the
  3877.      system property "user.timezone". The JVM  is supposed to set this
  3878.      value. In releases such as JDK 1.1 the value of user.timezone was often
  3879.      not set to anything, so TimeZone.getDefault() used its own built in
  3880.      "fallback" value (the default when there is no default value). In later
  3881.      JDK 1.1 releases and in JDK 1.2 the setting of the value of
  3882.      user.timezone is much better and the "fallback" value is now GMT
  3883.      (Greenwich Mean Time). Up until JDK 1.1.3, the fallback value was "PST"
  3884.      (North American Pacific Timezone).
  3885.  
  3886.  13. (Sect. 9) Do all the standard objects use the same default timezone?
  3887.  
  3888.      [*] Not until JDK 1.2. In JDK 1.1, Date.toString() and Calendar used
  3889.      the value of TimeZone.getDefault() which could often be undefined (see
  3890.      the previous question). In JDK 1.1, The Calendar in a SimpleDateFormat
  3891.      was set to the 1st timezone resource for the locale (for the US this is
  3892.      PST).
  3893.  
  3894.      System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() );
  3895.      sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
  3896.      System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() );
  3897.      Calendar cal = Calendar.getInstance();
  3898.      System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() );
  3899.  
  3900.      When run on a system running JDK 1.1.6, NOT in the North American
  3901.      Pacific Time nor in the GMT timezone results in:
  3902.  
  3903.      Timezone default = GMT
  3904.      Date format TZ = PST
  3905.      Calendar TZ = GMT
  3906.  
  3907.      This example shows two bugs, the value of user.timezone is undefined,
  3908.      so its defaulting to GMT (see discussion of TimeZone.getDefault()) and
  3909.      it shows that the DateFormat depends on the 1st locale entry which in
  3910.      this case is PST.
  3911.  
  3912.      If you don't want the DateFormat to use the Locale timezone, see the
  3913.      code provided below.
  3914.  
  3915.  14. (Sect. 9) If I explicitly set the default timezone, don't I need code
  3916.      to choose between (a) the daylight savings version or (b) the standard
  3917.      version of a timezone?
  3918.  
  3919.      [*] No. The ID that you use to select a timezone with
  3920.      TimeZone.getTimeZone refers to a predefined timezone that contains
  3921.      daylight savings information (when applicable). For example, the
  3922.      following code selects the timezone used in New York, USA.
  3923.  
  3924.      // Get the North American Eastern Time definition.
  3925.      TimeZone theTz = TimeZone.getTimeZone( "EST" );
  3926.      // get a really detailed date format and set it to the right timezone
  3927.      DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG,
  3928.      DateFormat.LONG );
  3929.      df.setTimeZone( theTz );
  3930.      // create a date in the locale's calendar, set its timezone and hour.
  3931.      Calendar day = Calendar.getInstance();
  3932.      day.setTimeZone( theTz );
  3933.      day.set( 1998, Calendar.FEBRUARY, 1 );
  3934.      day.set( Calendar.HOUR, 12 );
  3935.  
  3936.      // print that date/time and that date/time 150 full days of milliseconds later.
  3937.      System.out.println( df.format( day.getTime() ) );
  3938.      System.out.println( df.format(
  3939.      new Date( day.getTime().getTime() +    // get the millis
  3940.              150L*24*60*60*1000L ) ) );     // add exactly 150 days of millis
  3941.  
  3942.      Results in:
  3943.  
  3944.      February 1, 1998 12:00:00 PM EST
  3945.      July 1, 1998 1:00:00 PM EDT
  3946.  
  3947.      Notice that this example selected something refered to as "EST", but
  3948.      that this TimeZone was aware of the daylight savings time change and
  3949.      either printed as "EST" or "EDT".
  3950.  
  3951.      The confusion is reduced in JDK 1.2, you can use longer TimeZone IDs
  3952.      each maps to its own set of text resources. For example the following
  3953.      IDs are 5 hour West of GMT and have various DST rules:
  3954.      "America/Nassau", "America/Montreal", "America/Havana",
  3955.      "America/Port-au-Prince", "America/Grand_Turk", "America/New_York" and
  3956.      "EST".
  3957.  
  3958.      You can look at a list of other timezone names and offsets in the file
  3959.      $JAVAHOME/src/java/util/TimeZone.java
  3960.  
  3961.  15. (Sect. 9) How do I create my own Time Zone to apply to dates?
  3962.  
  3963.      [*] You can create a TimeZone object with the GMT offset of your
  3964.      choice. The following code creates British Time, a timezone that was
  3965.      not defined in 1.1.
  3966.  
  3967.      britTime = new SimpleTimeZone(0*ONE_HOUR, "Europe/London" /*GMT/BST*/,
  3968.          Calendar.MARCH,  -1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
  3969.          Calendar.OCTOBER,-1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
  3970.      1*ONE_HOUR),
  3971.  
  3972.      TimeZone.setDefault( britTime );
  3973.  
  3974.      Or you can then apply that TimeZone to a particular Calendar object
  3975.      like so:
  3976.  
  3977.      Calendar myCal = Calendar.getInstance();
  3978.      myCal.setTimeZone( britTime );
  3979.  
  3980.      If you are running 1.2, You can choose this existing timezone as the
  3981.      default with the code:
  3982.  
  3983.      TimeZone.setDefault( TimeZone.getTimeZone( "Europe/London" ) );
  3984.  
  3985.      Note that BST is defined from JDK 1.1 and later, but it is Bangladesh
  3986.      Standard Time. For a longer example of creating and testing the British
  3987.      timezone, Tony Dahlman provides a nice example in his BSumTime.java
  3988.      code.
  3989.  
  3990.  16. (Sect. 9) How do I create the BST timezone specifically?
  3991.  
  3992.      [*] You can create an arbitrary TimeZone object with the code below. In
  3993.      most or all other timezones, daylight savings time is handled
  3994.      automatically and internally. But GMT is the reference for all other
  3995.      timezones, and so does not have the summertime update applied
  3996.      automatically. The rules for BST can be found at
  3997.      http://www.ast.cam.ac.uk/pubinfo/leaflets/summer/summer.html
  3998.  
  3999.      Here is the code to create a British Summer Time timezone that is
  4000.      offset one hour from GMT between two dates:
  4001.  
  4002.      import java.util.*;
  4003.      import java.text.*;
  4004.      // create a BST timezone (code courtesy of Tony Dahlman).
  4005.  
  4006.      public static GregorianCalendar setBritSummTime(String zoneName){
  4007.         // Set up the default GMT0BST time zone
  4008.         SimpleTimeZone bst_tz =
  4009.            new SimpleTimeZone( 0,   // no offset from GMT
  4010.                         zoneName,   // individualized tz id
  4011.          // last Sun Mar 1AM
  4012.          Calendar.MARCH,-1,Calendar.SUNDAY,1*60*60*1000,
  4013.          // last Sun Oct 2AM
  4014.          Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000
  4015.                         );
  4016.         SimpleTimeZone.setDefault(bst_tz);
  4017.  
  4018.         // Apply TimeZone to create a Calendar object for UK locale
  4019.         return (new GregorianCalendar(bst_tz,Locale.UK) );
  4020.      }
  4021.  
  4022.  
  4023.      and here is how you would print out values using BST:
  4024.  
  4025.      // create a template for printing the date
  4026.      DateFormat df = DateFormat.getTimeInstance(
  4027.                         DateFormat.LONG,Locale.UK);
  4028.  
  4029.      // tell the template to use BST tz.
  4030.      df.setTimeZone(TimeZone.getDefault());
  4031.      System.out.println("Using British Summer Time "
  4032.                        +"the time is: "
  4033.                        + df.format( BritishSummerTime.getTime() ) );
  4034.  
  4035.      // Now get and compare with current time in GMT
  4036.      df.setTimeZone(TimeZone.getTimeZone("GMT") );
  4037.      System.out.println("\nCurrent time in GMT is: "
  4038.                        + df.format(BritishSummerTime.getTime() ) );
  4039.  
  4040.  
  4041.      In the winter, this BST zone is aligned with GMT; in the summer it is
  4042.      one hour later (4 a.m. GMT is 5 a.m. BST).
  4043.  
  4044.      You can look at a list of timezone names and offsets in the file
  4045.      $JAVAHOME/src/java/util/TimeZone.java
  4046.  
  4047.                 java.util.Calendar and java.util.GregorianCalendar
  4048.  
  4049.  17. (Sect. 9)How do I a create a specific date in the Gregorian Calendar?
  4050.  
  4051.      [*]If you have a Date use:
  4052.  
  4053.      myCal.setTime( myDate );
  4054.  
  4055.      If you have a set of integers representing the year, month and day of
  4056.      month use:
  4057.  
  4058.      Calendar myCal = Calendar.getInstance();
  4059.      myCal.set( 1998, Calendar.MARCH, 15 );
  4060.  
  4061.      Note: Months start with January = 0!
  4062.  
  4063.  18. (Sect. 9) How do I use a GregorianCalendar to extract a few fields from
  4064.      a Date?
  4065.  
  4066.      [*]The following code shows how to get some fields from a Date.
  4067.  
  4068.      Calendar g = Calendar.getInstance();
  4069.      g.setTime( aDate );
  4070.      int year = g.get( Calendar.YEAR );
  4071.      int mon = g.get( Calendar.MONTH );
  4072.      int date = g.get( Calendar.DATE );
  4073.      mon++;             // in class Calendar & GregCal, months run 0-11 ;-(
  4074.      System.out.println( mon + "/" + date + "/" + year);
  4075.  
  4076.      If you want to build a string that has a formated date consider using
  4077.      SimpleDateFormat.format().
  4078.  
  4079.  19. (Sect. 9) Some people use Calendar.getInstance() while others use new
  4080.      GregorianCalendar(). Which one is the correct way to get a Calendar?
  4081.  
  4082.      [*] Either way is correct, it depends on what you want to be able to
  4083.      do. You should use Calendar.getInstance(), if you want your code to be
  4084.      ready when the loading of other Calendars are added to the JDK and some
  4085.      other calendar is the default for the locale. A particular locale might
  4086.      have configured a Hebrew or Islamic Calendar as the default calendar
  4087.      and you might want a user to enter a date in his own Calendar, i.e.
  4088.      1-Jan-2000 (Gregorian) = 23-Tevet-576 (Hebrew) = 24-Ramadan-1420
  4089.      (Islamic). If you really are trying to place a particular Gregorian
  4090.      date, i.e. 4-July-1776, into a Date object, you might as well create a
  4091.      GregorianCalendar directly.
  4092.  
  4093.  20. (Sect. 9) I changed a field using Calendar.set() and then I checked
  4094.      another field. Its value is inconsistent with the value I just set.
  4095.      What is going on?
  4096.  
  4097.      [*]In JDK 1.1.0 the Calendar class did not update all of its fields
  4098.      until you called getTime to retrieve the Date that cooresponds to the
  4099.      fields in the Calendar. To get the earlier version of the Calendar to
  4100.      "turn the crank" and calculate all fields you can use the trick:
  4101.  
  4102.      myCal.setTime( myCal.setTime() )     // pull the date out and put it back
  4103.      in.
  4104.  
  4105.  21. (Sect. 9) When I create the date July 4th, 1776 using new
  4106.      GregorianCalendar( 1776, 7, 4 ) the month is off by one. What is the
  4107.      problem?
  4108.  
  4109.      [*]You need to be be aware that months start with January equal to 0. A
  4110.      better way to create that date would be:
  4111.  
  4112.      independanceDayUSA = new GregorianCalendar( 1776, Calendar.JULY, 4 );
  4113.  
  4114.  22. (Sect. 9)Why aren't there constants for milliseconds per day, week or
  4115.      year?
  4116.  
  4117.      [*]The short answer is: these values are not constants. While some date
  4118.      calculations would find these useful, it is important to remember that
  4119.      in areas with daylight savings time rules, there are two days per year
  4120.      that are not 24 hours long, therefore not all weeks are the same length
  4121.      (2 out of 52). Also, because of leap years, not all years are the same
  4122.      length.
  4123.  
  4124.      If you adding values to a calendar consider using either add or roll;
  4125.      for example:
  4126.  
  4127.      myCal.add(Calendar.YEAR, 1 );  // get a value 1 year later.
  4128.  
  4129.  23. (Sect. 9) By my count the week of the Year is off by one. What is the
  4130.      problem?
  4131.  
  4132.      [*]The GregorianCalendar class uses the value set by
  4133.      setMinimalDaysInFirstWeek() to determine if the fractional week at the
  4134.      beginning of the year should be week 1 or week 0. If you don't change
  4135.      it, any fractional week could be week 1, depending on the value defined
  4136.      for the locale.
  4137.  24. (Sect. 9) What timezone does a calendar use when I don't explicitly set
  4138.      one?
  4139.  
  4140.      [*]The Calendar uses the TimeZone.getDefault() (see discussion under
  4141.      TimeZone).
  4142.  
  4143.  25. (Sect. 9) Should I stop using Date all together and just use Calendar?
  4144.  
  4145.      [*] Probably not. The Calendar class is a much larger than a Date
  4146.      object. Many other interfaces in standard APIs are defined using a Date
  4147.      object. Use Date objects to hold, store or communicate a date-time
  4148.      value. Use a Calendar object to manipulate a date-time value.
  4149.  
  4150.  26. (Sect. 9) The GregorianCalendar will not accept a date prior to 4713
  4151.      B.C. Why?
  4152.  
  4153.      [*]January 1, 4713 B.C. is the "epoch" date for the Julian Day calendar
  4154.      which was invented in the 16th century by the Joseph Justus Scaliger.
  4155.      "[T]he Julian day calendar, ... does not use individual years at all,
  4156.      but a cycle of 7980 astronomical years that counts a day at a time,
  4157.      with no fractional days, no mean year, and no leap years. He came up
  4158.      with his number by mulitplying three chronological cycles: an 18-year
  4159.      solar cycle, a 19-year lunar cycle, and the 15-year indication period
  4160.      used by Romans. All three cycles began together at the same moment at
  4161.      the start of the "Julian cycle. ... [This] Calendar lives on among
  4162.      astronomers."
  4163.      -- David Ewing Duncan, "Calendar", Avon Books, 1998; p 207
  4164.  
  4165.      Note that the Julian Day calendar is not the same as the Julian
  4166.      calendar. The Julian Calendar is named for Julius Caesar. The Julian
  4167.      Calendar was used in the Europe from what we now call January 1, 45
  4168.      B.C. until at least October 4, 1582 and is still used today by the
  4169.      Eastern Orthodox Church to date holidays.
  4170.  
  4171.      The limitation on dates prior to 4713 BC has been dropped in JDK 1.2.
  4172.  
  4173.  27. (Sect. 9) The Calendar class is said not to handle certain historical
  4174.      changes. Can you explain some of the limitations?
  4175.  
  4176.      [*]The date of change from the Julian to the Gregorian calendar depends
  4177.      on where you lived at the time. The date can vary from 1582 (most
  4178.      Catholic countries, which of course followed the Papal edict) to 1949
  4179.      (China). The date of the cutover from using the Julian Calendar (leap
  4180.      years ever 4 years) to using the Gregorian Calendar (every 4 years,
  4181.      except every 100 unless divisable by 400) is controlled by the method
  4182.      GregorianCalendar.setGregorianChange(Date).
  4183.  
  4184.      It is also the case that January 1 was not always the beginning of the
  4185.      year. January 1 was standardized by Julius Caesar in 45 B.C. and Pope
  4186.      Gregory XIII in 1582, but others who used the Julian Calendar between
  4187.      those dates used other dates for New Years Day. (Anyone who has ever
  4188.      been involved in a standardization effort may find it interesting that
  4189.      neither an emperor nor a pope could actually complete the
  4190.      standardization effort).
  4191.  
  4192.      The Calendar class uses a TimeZone which does not handle historical
  4193.      changes, i.e. the SimpleTimeZone contains only two dates the "spring
  4194.      forward" and "fall back" dates and a date that the DST starts (see
  4195.      SimpleTimeZone.setStartYear() ). If the local definitions have changed
  4196.      then a date/time may not accurately reflect the historical local time.
  4197.  
  4198.      As noted above, the Date object does not usually include leap seconds,
  4199.      unless your hardware includes leap seconds.
  4200.  
  4201.      While the Calendar class is more than useful for international
  4202.      business, it may not be what you want for doing UTC timebased
  4203.      calculations or historical dates and times without a more careful
  4204.      analysis of its design limits.
  4205.  
  4206.                java.text.DateFormat and java.text.SimpleDateFormat
  4207.  
  4208.  28. (Sect. 9) How do I convert a date in one format to another?
  4209.  
  4210.      [*] The following code illustrates the technique:
  4211.  
  4212.      import java.text.*;
  4213.      public class DateTest {
  4214.        public static void main( String[] args ) {
  4215.          SimpleDateFormat df1 =
  4216.            new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
  4217.          SimpleDateFormat df2 =
  4218.            new SimpleDateFormat("dd-MMM-yy");
  4219.          String startdatetime = "1998-09-09 06:51:27.0";
  4220.  
  4221.          try {
  4222.            System.out.println("Date is " +
  4223.              df2.format( df1.parse(startdatetime) ));
  4224.          } catch (ParseException pe) {
  4225.            System.out.println("ParseException " + pe );
  4226.          }
  4227.        }
  4228.      }
  4229.  
  4230.      When run, the program outputs "Date is 09-Sep-98"
  4231.  29. (Sect. 9) How do I use DateFormat to parse a string containing a date?
  4232.  
  4233.      [*] The easiest way to parse a date that is in a known format is to use
  4234.      SimpleDateFormat.parse().
  4235.  
  4236.      DateFormat df = new SimpleDateFormat( "HH:mm" );
  4237.      df.setTimeZone( TimeZone.getDefault() ); // if using JDK 1.1 libraries.
  4238.      df.setLenient( false );                  // to not allow 26:65 etc.
  4239.      Date lateLunchOnDayZero = df.parse( "12:30" );
  4240.      System.out.println( lateLunchOnDayZero );
  4241.  
  4242.      The above code would result in (when in the MST timezone).
  4243.  
  4244.      Thu Jan 01 12:30:00 MST 1970
  4245.  
  4246.      To parse other date and time fields, refer to the SimpleDateFormat
  4247.      documentation.
  4248.  
  4249.  30. (Sect. 9) How do I use a DateFormat to create a text string from a
  4250.      Date?
  4251.  
  4252.      [*] The easiest way to create a string from a date is to use a
  4253.      SimpleDateFormat.format(). The following code illustrates how this can
  4254.      be done.
  4255.  
  4256.      DateFormat df = new SimpleDateFormat( "yyyy.MMM.dd HH:mm:ss.SSS z" );
  4257.      df.setTimeZone( TimeZone.getDefault() ); // JDK 1.1
  4258.      System.out.println( df.format( d ) );    // where d is a Date
  4259.  
  4260.      For other possible fields from the calendar, see the document for
  4261.      SimpleDateFormat.
  4262.  
  4263.  31. (Sect. 9) What timezone does a SimpleDateFormat use when I don't
  4264.      specify one?
  4265.  
  4266.      [*]In JDK 1.1, the SimpleDateFormat uses the first timezone defined for
  4267.      the locale. In JDK 1.2, it uses the default timezone. See the
  4268.      discussion above on how this differs from the Calendar class).
  4269.  
  4270.  32. (Sect. 9) I'm not yet using JDK 1.2 and I don't want the DateFormat to
  4271.      use the 1st timezone for the locale. How do I change the timezone in a
  4272.      SimpleDateFormat to use a different timezone?
  4273.  
  4274.      [*] The following code sets the timezone of a DateFormat to the current
  4275.      default.
  4276.  
  4277.      DateFormat df = DateFormat.getDateInstance();
  4278.      df.setTimeZone(TimeZone.getDefault());
  4279.  
  4280.      or to set it to a timezone of your chioce.
  4281.  
  4282.      df.setTimeZone(TimeZone.getTimeZone( "MST" ) ) // Mtn Time, Denver USA
  4283.  
  4284.  33. (Sect. 9) What century is assumed when I use a two digit year in a
  4285.      SimpleDateFormat string?
  4286.  
  4287.      [*]In JDK 1.1, the default start for the century used by
  4288.      SimpleDateFormat for 2 digit years is 80 years before the current date.
  4289.  
  4290.      This means that in 1998: 1 = 2001, 2 = 2002, ... 17 = 2017, 18 = 2018,
  4291.      19 = 1919, 20 = 1920, ... 98 = 1998, 99 = 1999,
  4292.  
  4293.      In JDK 1.2 you can change this "default century start date" with the
  4294.      method set2DigitYearStart( Date) and get its current value
  4295.      with the method get2DigitYearStart(). One thing to note is that since
  4296.      set2DigitYearStart takes a date not a year, you can have your default
  4297.      century begin at any day or hour.
  4298.  
  4299.      When running under JDK 1.1, it is probably best to avoid two-digit year
  4300.      fields, when the dates entered could possibly fall outside of the range
  4301.      -- now less 80 years and now plus 20 years. If you want to allow
  4302.      two-digit year fields in JDK 1.2 and beyond, consider setting the
  4303.      2DigitYearStart property to something appropriate,  For example, set it
  4304.      to today, when all dates to be entered are in the future (i.e. an
  4305.      expiration date), or set it to today less 100 years, when the value is
  4306.      always in the past (i.e. birthdate, death date).
  4307.  
  4308.  34. (Sect. 9) Does the above mentioned limitation of 2 digit years in JDK
  4309.      1.1 mean that java.text.SimpleDateFormat is not Y2K compliant?
  4310.  
  4311.      [*] No. It means that any code you write that (1) allows the entry of 2
  4312.      digit years and (2) does not make sure they are in an appropriate
  4313.      century, would not pass a careful Y2K analysis. This code was put here
  4314.      so you could sensibly read old files with non-Y2K compliant dates, not
  4315.      so you could create new ones. Once you are using JDK 1.2 it is better
  4316.      to set the 2DigitYearStart property to something appropriate for any
  4317.      two-digit year field which you are parsing.
  4318.  
  4319.                        java.sql.Date and java.sql.TimeStamp
  4320.  
  4321.  35. (Sect. 9) What timezone does a java.sql.date use when converting to an
  4322.      SQL DATE?
  4323.  
  4324.      [*]This is another hidden use of the default java.util.TimeZone. If you
  4325.      have carefully set every timezone in every Calendar and DateFormat you
  4326.      are using, but you don't set the default in java.util.TimeZone when a
  4327.      java.util.Date is converted to a java.sql.Date you may not end up with
  4328.      the value you expected in your database.
  4329.  
  4330.  36. (Sect. 9) When I print a jave.sql.Timestamp it doesn't include any
  4331.      milliseconds. What is the problem?
  4332.  
  4333.      [*] If you print the java.sql.Timestamp directly you will see this
  4334.      problem. The following code demonstrates this surprising behavior.
  4335.  
  4336.      // incorrect use of java.sql.Timestamp
  4337.      DateFormat df = new SimpleDateFormat( "MM/dd/yy hh:mm:ss.SSS a" );
  4338.      df.setTimeZone( TimeZone.getDefault() );    // needed in JDK 1.1
  4339.  
  4340.      java.sql.Timestamp t = new java.sql.Timestamp( 94, Calendar.JANUARY, 1,
  4341.              13, 45, 59, 987654321 );
  4342.      System.out.println( df.format( t ) ) ; // Wrong! no fractions of a second.
  4343.  
  4344.      The results of the above code are:
  4345.  
  4346.      01/01/94 01:45:59.000 PM
  4347.  
  4348.      The above code is using whatever is in the super class (java.util.Date)
  4349.      and assumes all of those parts are filled in. java.sql.Timestamp could
  4350.      have stored the whole milliseconds in the millisecond part of a
  4351.      java.util.Date, and stored the nanoseconds that are not whole
  4352.      milliseconds in an additional field. They chose to ignore the fractions
  4353.      of a second in the java.util.Date and put all fractional parts in an
  4354.      additional nanosecond field.
  4355.  
  4356.      The following code shows how to convert a java.sql.timestamp to a
  4357.      java.util.Date.
  4358.  
  4359.      Date d = new Date(t.getTime() + (t.getNanos() / 1000000 )); // 1 Milli = 1x10^6
  4360.      Nanos
  4361.      System.out.println( df.format( d ) ) ; // Right! At least we have the millis
  4362.  
  4363.      The result of the above code is a better approximation of the timestamp
  4364.      value:
  4365.  
  4366.      01/01/94 01:45:59.987 PM
  4367.  
  4368.                        -------------------------------
  4369.  
  4370. 10. AWT
  4371.  
  4372.                           Text, Textfield, and TextArea
  4373.  
  4374.   1. (Sect. 10) How can I write text at an angle?
  4375.  
  4376.      [*] Check out http://www.nyx.net/~jbuzbee/font.html. Jim has some code
  4377.      to do exactly this. A good way to do it is to draw the text to an
  4378.      offscreen image and write an ImageFilter to rotate the image.
  4379.  
  4380.      Also, from JDK 1.2 on, the Java 2D API handles arbitrary shapes, text,
  4381.      and images and allows all of these to be rotated, scaled, skewed, and
  4382.      otherwise transformed in a uniform manner. There is more info about the
  4383.      2D API at http://java.sun.com/products/java-media/2D/index.html and
  4384.      http://developer.javasoft.com/developer/technicalArticles/
  4385.  
  4386.   2. (Sect. 10) How do you change the font type and size of text in a
  4387.      TextArea?
  4388.  
  4389.      [*] Like this.
  4390.  
  4391.      myTextArea.setFont(new Font("NAME", <STYLE>, <SIZE>));
  4392.  
  4393.      where:
  4394.         o NAMEis the name of the font (e.g. Dialog or TimesRoman).
  4395.         o <STYLE> is Font.PLAIN, Font.ITALIC, Font.BOLD or any additive
  4396.           combination (e.g. Font.ITALIC+Font.BOLD).
  4397.         o <SIZE> is the size of the font, e.g. 12.
  4398.  
  4399.      Example: new Font("TimesRoman", Font.PLAIN, 18);
  4400.  
  4401.   3. (Sect. 10) Can you have different fonts for individual words in a
  4402.      TextArea?
  4403.  
  4404.      [*] No. If you're trying to write a word processor, use the Canvas
  4405.      class to render on. Note that this can be done using the Swing JText
  4406.      classes.
  4407.  
  4408.   4. (Sect. 10) How much text can be put in a TextArea?
  4409.  
  4410.      [*] TextArea just uses the corresponding widget of the underlying
  4411.      window system. It will be bounded by the limit imposed in the native
  4412.      window system. In Windows 95 TextAreas can hold about 28Kb. The native
  4413.      widget allows 32Kb, but there is some overhead which reduces the amount
  4414.      available to the programmer. The limit is removed in JTextComponent in
  4415.      Swing (JDK 1.2) which dispenses with peer controls.
  4416.  
  4417.   5. (Sect. 10) How do I clear the contents of a TextArea?
  4418.  
  4419.      [*] Set it to an empty String with this:
  4420.  
  4421.      area.setText("");
  4422.  
  4423.   6. How do I get back to a normal echo after I have used
  4424.      TextField.setEchoChar('*')?
  4425.  
  4426.      [*] TextField.setEchoChar('\0') works on most Windows-based
  4427.      browsers...but for most other platforms (i.e. Netscape under UNIX), it
  4428.      just locks up the textfield.
  4429.  
  4430.      There is only one good solution, and that is to make two TextFields on
  4431.      top of each other, one normal, and one with .setEchoChar('*'), and
  4432.      switch between them.
  4433.  
  4434.   7. (Sect. 10) How do I get word wrap in a TextArea?
  4435.  
  4436.      [*] It's a little obscure. Creating a TextArea with no horizontal
  4437.      scrollbar causes wrapping to occur automatically. The idea is that if
  4438.      you ask for a scroll to scroll viewing over to the right, there is no
  4439.      reason for the widget to do word wrap. So take away the scrollbar, and
  4440.      word wrap will be done instead.
  4441.  
  4442.      Supply TextArea.SCROLLBARS_NONE or TextArea.SCROLLBARS_VERTICAL_ONLY to
  4443.      the TextArea constructor to get word wrap. By default, a TextArea is
  4444.      created with both horizontal and vertical scrollbars.
  4445.  
  4446.   8. (Sect. 10) How can I limit a TextField to no more than N characters, or
  4447.      to only allow numeric input?
  4448.  
  4449.      [*] The approach is to look at keystrokes as they happen, and disallow
  4450.      input that does not meet your criteria.
  4451.  
  4452.      A neat variation is to extend the basic AWT component, and in your
  4453.      subclass also include the handler that will look at the keystrokes.
  4454.      This bundles everything neatly in one place. The code may look like:
  4455.  
  4456.      import java.awt.*;
  4457.      import java.awt.event.*;
  4458.      public class XCTextField extends java.awt.TextField implements
  4459.      java.awt.event.TextListener {
  4460.  
  4461.          public XCTextField(int columns) {
  4462.              super(columns);
  4463.              enableEvents(AWTEvent.FOCUS_EVENT_MASK);
  4464.              addTextListener(this);
  4465.          }
  4466.  
  4467.          // other constructors may be useful, too
  4468.  
  4469.          public void textValueChanged(java.awt.event.TextEvent event) {
  4470.              int col = this.getColumns();
  4471.              int len = getText().length();
  4472.           // int caret = getCaretPosition();
  4473.  
  4474.              if (col > 0 && len  > col) {
  4475.              // or if the char just entered is not numeric etc.
  4476.                      String s = this.getText();
  4477.                      Toolkit.getDefaultToolkit().beep();
  4478.                      this.setText(s.substring(0,col));
  4479.                      this.setCaretPosition(col-1);  // caret at end
  4480.              }
  4481.  
  4482.          }
  4483.  
  4484.          public void processFocusEvent(java.awt.event.FocusEvent e) {
  4485.          // this routine highlights according to focus gain/loss.
  4486.              super.processFocusEvent(e);
  4487.              int id = e.getID();
  4488.              if (id==java.awt.event.FocusEvent.FOCUS_GAINED)
  4489.                  this.selectAll();
  4490.              else if (id==java.awt.event.FocusEvent.FOCUS_LOST)
  4491.                  this.select(0,0);
  4492.          }
  4493.      }
  4494.  
  4495.      Here is a much briefer example, which very cleverly does the work in
  4496.      the Listener. Oracle really dislikes the "apostrophe" character in a
  4497.      data text fields, as it is interpreted as part of an SQL statement.
  4498.      Here is the code that James Cloughley wrote to suppress apostrophes
  4499.      ("ticks") in a TextField.
  4500.  
  4501.      import java.awt.*;
  4502.      import java.awt.event.*;
  4503.      public class NoTick extends KeyAdapter {
  4504.          final char tick = '\'';
  4505.  
  4506.          public void keyPressed( KeyEvent event ) {
  4507.              TextComponent tc = ( TextComponent )event.getSource();
  4508.              char c = event.getKeyChar();
  4509.              if ( c == tick ) { event.consume(); }
  4510.          }
  4511.      }
  4512.  
  4513.      Use it like this:
  4514.  
  4515.      TextField sometextfield = new TextField();
  4516.      sometextfield.addKeyListener( new NoTick() );
  4517.  
  4518.  
  4519.      Brief and clever - make the event handler consume unwanted characters.
  4520.      However, it doesn't filter out text that arrives in the component via
  4521.      cut & paste! If you use ctrl-v to paste, you get key events for the
  4522.      ctrl and v, but not for the characters that are pasted.
  4523.  
  4524.      Finally, check out iDate, iTime, and iNumeric from IBM's alphaworks
  4525.      javabeans, available free at http://www.alphaworks.ibm.com/alphaBeans.
  4526.      These beans do the kind of validation you want.
  4527.  
  4528.                                 Size and Position
  4529.  
  4530.   9. (Sect. 10) I use add(Component) to add Components to the Container. Is
  4531.      there any way to explicitly set the z-order of these Components?
  4532.  
  4533.      [*] JDK 1.0 has no way to explicitly set the z-order of components. You
  4534.      can try it heuristically, based on the browser you're using, or you can
  4535.      use CardLayoutManager to ensure the panel you want is at the front.
  4536.  
  4537.      In JDK 1.1, the z-order of components ("z-order" means "front-to-back"
  4538.      order, i.e. which window is in front of which) can be controlled by
  4539.      using the the method add(Component comp, int index). By default,
  4540.      components are added 0 to N. The method paint of class Container paints
  4541.      its visible components from N to 0.
  4542.  
  4543.  10. (Sect. 10) How can I get the dimensions and resolution of the screen?
  4544.  
  4545.      [*] Use
  4546.  
  4547.      java.awt.Toolkit.getDefaultToolkit().getScreenSize()
  4548.  
  4549.      or
  4550.  
  4551.      java.awt.Toolkit.getDefaultToolkit().getScreenResolution()
  4552.  
  4553.      Screen resolution is in dots-per-inch.
  4554.  
  4555.      Take a look in the Toolkit class for other useful methods.
  4556.  
  4557.      Toolkit.getDefaultToolkit().getColorModel().getPixelSize()
  4558.  
  4559.      gets you the color model in terms of bits per pixel.
  4560.  
  4561.      Math.pow(2, Toolkit.getDefaultToolkit().
  4562.          getColorModel().getPixelSize())
  4563.  
  4564.      gets you the color model in terms of number of colors. Or use this:
  4565.  
  4566.      1 << Toolkit.getDefaultToolkit().
  4567.          getColorModel().getPixelSize()
  4568.  
  4569.      That does a shift left to calculate the power of two.
  4570.  
  4571.  11. (Sect. 10) How do I allow for the size of the title bar and border when
  4572.      I draw a Frame?
  4573.  
  4574.      [*] Use MyFrame.getInsets(). This returns a java.awt.Insets object
  4575.      which has four ints: top, left, bottom, right, giving the number of
  4576.      pixels each of those margins are inset from the top. You can use these
  4577.      value to adjust the Dimension object returned by component.getSize().
  4578.  
  4579.      If you are doing this in the constructor you need to ensure that the
  4580.      Frame's peer object is created first. Otherwise the Insets object
  4581.      returned by getInsets() will have all zero values. Make a call to
  4582.      Frame.addNotify() to have the peer created.
  4583.  
  4584.  12. (Sect. 10) How do I resize a List? I had a List defined as
  4585.  
  4586.      List tlist = new List(10);
  4587.  
  4588.      but the Strings in the list were 80 characters long and only the first
  4589.      15 were being shown. I was not able to resize the List to display the
  4590.      contents without using the scroll bar.
  4591.  
  4592.      [*] A List cannot be resized in a constructor, so add the following to
  4593.      the Applet (or wherever):
  4594.  
  4595.      public void paint (Graphics g) {
  4596.          tlist.setSize(200,200);
  4597.      }
  4598.  
  4599.      Then before showing panel/frame with the List:
  4600.  
  4601.      tlist.resize(400,400);
  4602.  
  4603.  13. (Sect. 10) How can my program tell when a window is resized?
  4604.  
  4605.      [*] Override the setBounds(int,int,int,int) method of Component to do
  4606.      what you want. Of course, have it call super.setBounds() as well. Note
  4607.      that setBounds() replaces reshape() which is deprecated.
  4608.  
  4609.      Note the new APIs call the deprecated APIs instead of the other way
  4610.      round. For example, Component.setBounds calls Component.reshape,
  4611.      instead of reshape calling setBounds. This is because the AWT sometimes
  4612.      needs to call these for its own purposes. If it called the old one
  4613.      which then called the new one, and you overrode the new one, the AWT
  4614.      would (wrongly) not call your routine. By having the AWT call the new
  4615.      one (and then the new one call the old one), any overrides of the new
  4616.      one will correctly be called by the AWT as needed. If that didn't make
  4617.      sense, forget I mentioned it.
  4618.  
  4619.  14. (Sect. 10) How do I center a dialog box?
  4620.  
  4621.      [*] You cannot currently get the applet's absolute screen coordinates.
  4622.      Its location (0,0) is relative to the browser, not the screen itself.
  4623.      But you can center something that it pops up or displays centered on
  4624.      the screen with code like this:
  4625.  
  4626.      Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
  4627.      my_window.move(
  4628.       ( screen.width - window.size().width ) / 2,
  4629.       ( screen.height - window.size().height ) / 2 );
  4630.  
  4631.      my_window.show().
  4632.  
  4633.      In a related fashion, you can center something on its parent like this.
  4634.      Note the intelligent use of APIs like translate() to do the work for
  4635.      you.
  4636.  
  4637.      void center(Component parent) {
  4638.          pack();
  4639.  
  4640.          Point p = parent.getLocation();
  4641.          Dimension d = parent.getSize();
  4642.          Dimension s = getSize();
  4643.  
  4644.          p.translate((d.width - s.width) / 2,
  4645.                      (d.height - s.height) / 2);
  4646.          setLocation(p);
  4647.      }
  4648.  
  4649.  15. (Sect. 10) How can I get the absolute mouse coordinates?
  4650.  
  4651.      [*] You mean, if the browser is about 640x480, you want a y-coord
  4652.      between 0 and 480. If the browser window is about 800x600 you want a
  4653.      y-coord between 0 and 600. This might be needed for a pop-up menu,
  4654.      where you want to pop up at the absolute mouse position.
  4655.  
  4656.      The approach is to sum up the event's (x,y) and the locations of the
  4657.      target and its parents until there is no parent. Though on some
  4658.      browsers, it seems this is not reliable. [Better suggestions are
  4659.      solicited.]
  4660.  
  4661.  16. (Sect. 10) How do I detect a resize of a Frame or other Component?
  4662.  
  4663.      [*] If you are using JDK 1.0.2, you can override the reshape(int, int,
  4664.      int, int) method of Component to do what you want; of course, have it
  4665.      call super.reshape() as well.
  4666.      In JDK 1.1.x, setBounds() replaces reshape(), which is deprecated -
  4667.      however, there is a better way of detecting the resize using the new
  4668.      event model, than overriding setBounds(). Note the new APIs call the
  4669.      depecated one.
  4670.  
  4671.      The proper way to detect the resize in 1.1.x is to register a
  4672.      ComponentListener on the Frame, like this:
  4673.  
  4674.      import java.awt.*;
  4675.      import java.awt.event.*;
  4676.  
  4677.      class MyFrame extends Frame {
  4678.          public MyFrame() {
  4679.              addComponentListener(new CmpAdapter());
  4680.          }
  4681.  
  4682.          class CmpAdapter extends ComponentAdapter {
  4683.              public void componentResized(ComponentEvent evt) {
  4684.                  //doSomething();
  4685.              }
  4686.          }
  4687.      }
  4688.  
  4689.      Alternatively, the same effect can be achieved like this:
  4690.  
  4691.      class MyFrame extends Frame implements ComponentListener {
  4692.          public MyFrame() {
  4693.              addComponentListener(this);
  4694.          }
  4695.  
  4696.          public componentHidden(ComponentEvent evt) { }
  4697.          public componentMoved(ComponentEvent evt) { }
  4698.          public componentShown(ComponentEvent evt) { }
  4699.          public componentResized(ComponentEvent evt) {
  4700.              //doSomething
  4701.          }
  4702.      }
  4703.  
  4704.      Or even with an anonymous inner class
  4705.  
  4706.        public MyFrame() {
  4707.                addComponentListener(new ComponentAdapter() {
  4708.                  public void componentResized(ComponentEvent evt) {
  4709.                    // doSomething;
  4710.              }
  4711.            } );
  4712.          }
  4713.  
  4714.  17. (Sect. 10) What are those preferredSize() and minimumSize() methods in
  4715.      Component?
  4716.  
  4717.      [*] Those methods allow a LayoutManager to calculate the preferred and
  4718.      minimum sizes of the Components it is arranging. You can control the
  4719.      values that the LayoutManager gets by creating subclasses of the
  4720.      Components you are using and overriding these methods.
  4721.  
  4722.                                 Drawing and Pixels
  4723.  
  4724.  18. (Sect. 10) How do I plot a single pixel to the screen?
  4725.  
  4726.      [*] Use g.drawLine(x1,y1,x1,y1) to draw a line one pixel in length. If
  4727.      you are drawing a very large number of individual pixels, consider
  4728.      using a java.awt.MemoryImageSource object and measure whether this
  4729.      offers better performance.
  4730.  
  4731.  19. (Sect. 10) Is it possible to draw a polygon or a line more than 1 pixel
  4732.      wide?
  4733.  
  4734.      [*] JDK 1.1.1 doesn't have support for this. The standard workaround
  4735.      for drawing a thick line is to draw a filled polygon. The standard
  4736.      workaround for drawing a thick polygon is to draw several polygons.
  4737.  
  4738.      There is a useful class at
  4739.      http://www.apl.jhu.edu/~hall/java/GraphicsUtil.html which extends the
  4740.      drawxxx and fillxxx methods of java.awt.Graphics. It adds a Line Width
  4741.      argument to most of the drawxxx methods, a Color argument to most of
  4742.      the drawxxx and fillxxx methods, and a Font argument to drawString and
  4743.      drawChars.
  4744.  
  4745.  20. (Sect. 10) How can I make an offscreen image with transparent pixels?
  4746.      How can I grab the pixel values from an offscreen image?
  4747.      How can I use AWT drawing primitives (e.g. drawString() or drawOval())
  4748.      on an image I created from an ImageProducer?
  4749.  
  4750.      [*] None of these things can be done.
  4751.  
  4752.      Despite the fact that there is only one class called Image in the AWT
  4753.      libraries, it suffers from a (currently undocumented) severe case of
  4754.      schizophrenia: The code behaves as though there are two unrelated types
  4755.      of Image. The first type are those created by the
  4756.      Component.createImage(int, int) call, known as "offscreen" images, and
  4757.      the second are those created by the
  4758.      Component.createImage(ImageProducer) call, or by the
  4759.      Toolkit/Applet.getImage() calls, which I will call "produced" images.
  4760.  
  4761.      The only common ground between these kinds of Image is the following:
  4762.         o You may find their width and height by the methods of the Image
  4763.           class.
  4764.         o You may use them as the argument to the various
  4765.           Graphics.drawImage() calls.
  4766.      The differences between these objects are the following:
  4767.         o You may not put transparent pixels into an offscreen - note that
  4768.           all Java primitives accept Color objects, which all represent
  4769.           completely opaque colours as if Produced from an int with the
  4770.           upper 8 bits equal to 0xff. (See also Question 8.3.)
  4771.         o You may not call Image.getGraphics() on a produced image, and
  4772.           hence may not use any AWT primitives.
  4773.         o You may not grab pixels from an offscreen image using
  4774.           PixelGrabber.
  4775.         o Anyone know of any other limitations?
  4776.      In these cases, "you may not" generally means "you may not
  4777.      successfully". Symptoms on attempting these range from Exceptions to
  4778.      garblings of the Image. Any or all of these restrictions may be removed
  4779.      in Java 1.2, which features a new 2D API. Wait and see.
  4780.      Workaround: cause a peer to be created for the Image, and then do the
  4781.      operation. It will work. You can add it to a Frame, for example. You do
  4782.      not have to show() the Frame. Causing the peer to be created is enough.
  4783.  
  4784.      There are some relevant bugs shown in the Java Developer Connection:
  4785.      Bug ID 4098505. Apparently, from the report from the Sun engineer,
  4786.      PixelGrabber is specified to work with offscreen images, just it is
  4787.      currently buggy, and invariably gets the wrong color model. No fix has
  4788.      been scheduled yet.
  4789.  
  4790.      Bug ID 4077718 reports that setting transparent Colors in offscreen
  4791.      images has been available since Java 1.2b1. I am personally unable to
  4792.      verify this.
  4793.  
  4794.      There is an incorrect answer from Sun to the third matter, of
  4795.      getGraphics() on produced images, in article 1501 in Questions&Answers.
  4796.  
  4797.  21. (Sect. 10) How can I grab a pixel from an Image object?
  4798.  
  4799.      [*] This is the purpose of the java.awt.image.PixelGrabber class. A
  4800.      fragment of code showing its use is:
  4801.  
  4802.      import java.awt.image.PixelGrabber;
  4803.      import java.awt.Image;
  4804.         ...
  4805.      public static int pixelValue(Image image, int x, int y) {
  4806.      // precondition: buffer must not be created from ImageProducer!
  4807.      // x,y should be inside the image,
  4808.      // Returns an integer representing color value of the x,y pixel.
  4809.          int[] pixel=new int[1];
  4810.          pixel[0]=0;
  4811.  
  4812.      // pixel grabber fills the array with zeros if image you are
  4813.      // trying to grab from is non existent (or throws an exception)
  4814.          PixelGrabber grabber = new PixelGrabber(image,
  4815.                                           x, y, 1, 1, pixel, 0, 0);
  4816.          try {
  4817.              grabber.grabPixels();
  4818.          } catch (Exception e) {System.err.println(e.getMessage());}
  4819.          return pixel[0];
  4820.      }
  4821.  
  4822.      By the way, one issue on working with images is that the Java VM will
  4823.      consume virtual memory pretty fast if you are loading lots of images
  4824.      without calling the Image.flush() method when done. The getImage()
  4825.      method probably caches old images so they aren't garbage collected.
  4826.  
  4827.                                   Other AWT FAQs
  4828.  
  4829.  22. (Sect. 10) How do I change the icon on my Frame or JFrame from the Java
  4830.      coffee cup to my own icon?
  4831.  
  4832.      [*] Just use
  4833.  
  4834.      f.setIconImage( Toolkit.getDefaultToolkit().getImage(iconfilename) );
  4835.  
  4836.  23. (Sect. 10) What's all this about subclassing Canvas and overriding
  4837.      paint() ? Can't I just do a getGraphics() for a component, and draw
  4838.      directly on that?
  4839.  
  4840.      [*] You can do that, and it might work up to a point (or it might not).
  4841.      A problem arises when the window system wants to refresh that component
  4842.      e.g. because it has been partially obscured and is now revealed. It
  4843.      calls paint(), and paint() has no knowledge of the other g.drawing()
  4844.      you have just done.
  4845.  
  4846.  24. (Sect. 10) But couldn't the AWT just remember what has been drawn to a
  4847.      Graphics context, and replicate that instead of calling paint()?
  4848.  
  4849.      [*] Possibly it could, but how do you unremember something that has
  4850.      been drawn? How do you start drawing over again with different
  4851.      contents? You could solve these by creating extra methods, but that is
  4852.      not how it works. In practice it is a lot simpler to be able to look at
  4853.      the paint method, and see explicitly all the things that will be done
  4854.      to draw that component. Bottom line: Use paint(), not g=getGraphics();
  4855.      g.drawString( ...
  4856.  
  4857.  25. (Sect. 10) When I call repaint() repeatedly, half my requests get lost
  4858.      and don't appear on the screen. Why is this?
  4859.  
  4860.      [*] repaint() just tells the AWT that you'd like a paint to happen. AWT
  4861.      will fold several adjacent repaint requests into one, so that only the
  4862.      most current paint is done. One possible workaround might be to use a
  4863.      clip rectangle and only paint the different areas that have changed.
  4864.  26. (Sect. 10) Why do I get this when using JDK 1.1 under X Windows?
  4865.  
  4866.      java.lang.NullPointerException
  4867.      at sun.awt.motif.MFramePeer.<init>(MFramePeer.java:59)
  4868.      at sun.awt.motif.MToolkit.createFrame(MToolkit.java:153)
  4869.      at java.awt.Frame.addNotify(Frame.java)
  4870.      at java.awt.Window.pack(Window.java)
  4871.  
  4872.      [*] There's a missing font on your system. Move font.properties from
  4873.      the "lib" subdirectory aside to font.properties.bak. Then it won't look
  4874.      for the font and fail to find it.
  4875.  
  4876.      The problem occurs because the Motif AWT libraries use the Font "plain
  4877.      Dialog 12 point" as a fall-back default font. Unfortunately, when using
  4878.      a remote X server sometimes this font isn't available.
  4879.  
  4880.      On an X terminal, the diagnostic may be slightly different, a segv
  4881.  
  4882.      % appletviewer HelloWorldApplet.html
  4883.      SIGSEGV 11* segmentation violation
  4884.      si_signo [11]: SIGSEGV 11* segmentation violation
  4885.      si_errno [0]: Error 0
  4886.      si_code [1]: SEGV_ACCERR [addr: 0x14]
  4887.  
  4888.      To determine which fonts you have, issue a command such as
  4889.  
  4890.      xlsfonts > ~/fonts.txt
  4891.  
  4892.      Then pick through the long list of fonts to determine which ones you
  4893.      want to use. The xfd program will let you look at a font:
  4894.  
  4895.      xfd -fn "your font name here" &
  4896.  
  4897.  27. (Sect. 10) Why is GridBagLayout so hard to use?
  4898.  
  4899.      [*] There are two reasons. First, while simple layouts are easy.
  4900.      detailed GUI layout is difficult. Second, GridBagLayout wasn't designed
  4901.      with human factors and ease of use in mind. If that bothers you (it
  4902.      bothers me) then don't use it. Create your GUI on several panels and
  4903.      use the other layout managers as appropriate to get the exact effect
  4904.      you want. The official story from the project leader of the AWT
  4905.      project, as explained to the Mountain View Java Users Group on December
  4906.      4 1996, is:
  4907.           "The case has been made and is now accepted that GridBagLayout is
  4908.           too hard to use for what it offers. GBL will continue to be
  4909.           supported, and something better and simpler will eventually be
  4910.           provided as well. This 'better GBL' can be used instead of GBL."
  4911.      Bottom line: nobody has to spend any effort on GBL, there are better
  4912.      alternatives available now, and it will be replaced by the SwingSet
  4913.      "SpringLayout" Springs & Struts style layout manager.
  4914.  
  4915.      SpringLayout was to be introduced as part of the Java Foundation
  4916.      Classes with JDK 1.2, but it was dropped from the beta release as the
  4917.      code was not ready in time. Javasoft generously made the preliminary
  4918.      code available and invited programmers to hack on it and submit the
  4919.      results.
  4920.  
  4921.  28. (Sect. 10) MyClass works fine except when I try to set a particular
  4922.      font. I just can't seem to get it to work in Win95, but I can get it to
  4923.      work on a MacOS and Unix.
  4924.  
  4925.      [*] You probably specified a font name that isn't available under your
  4926.      Win95 installation; this is one of those cross-platform differences
  4927.      that can bite you if you over-specify for one platform, like specifying
  4928.      "Arial" as a font and expecting it to work on something other than
  4929.      Windows.
  4930.  
  4931.      On both Windows 95 and Solaris 2.6, these fonts
  4932.         o Dialog
  4933.         o SansSerif
  4934.         o Serif
  4935.         o Monospaced
  4936.         o Helvetica
  4937.         o TimesRoman
  4938.         o Courier
  4939.         o DialogInput
  4940.         o ZapfDingbats
  4941.      are revealed by this code:
  4942.  
  4943.      import java.awt.*;
  4944.  
  4945.      class foonly {
  4946.          static public void main(String s[])
  4947.          {
  4948.              String n[]= new Frame().getToolkit().getFontList();
  4949.              for (int i=0;i<n.length; i++)
  4950.                  System.out.println(n[i]);
  4951.  
  4952.              System.exit(0);
  4953.          }
  4954.      }
  4955.  
  4956.      In other words, You can get a String array of the names of the fonts by
  4957.  
  4958.      String[] fonts = Toolkit.getDefaultToolkit().getFontList()
  4959.  
  4960.      The names of actual fonts like Helvetica, TimesRoman, and Courier are
  4961.      deprecated in JDK 1.1 in favor of font styles like SansSerif, Serif,
  4962.      and Monospaced (respectively). The font style will be mapped into the
  4963.      nearest actual font on a platform.
  4964.  
  4965.      The font styles are now mapped into a system font name using the
  4966.      entries in one of the font.properties files in $JAVAHOME/lib. There are
  4967.      multiple font.properties files corresponding to different locales. If
  4968.      you wanted a quick hack for testing, you could modify the file or add
  4969.      to it so a different mapping is done to a new font you want to try.
  4970.  
  4971.  29. (Sect. 10) I've made a Lightweight Component (a Component directly
  4972.      extending Component), and it keeps flickering/doesn't repaint itself
  4973.      properly. Why is this?
  4974.  
  4975.      [*] Lightweight Components, since they are notionally meant to be
  4976.      "transparent", aren't painted directly in response to repaint(), but in
  4977.      fact, Component.repaint() goes up the stack of Components until it
  4978.      finds an "Opaque" Heavyweight Component (necessarily a Container), and
  4979.      then calls repaint() on *that*.
  4980.  
  4981.      At this point, a call is eventually scheduled to Container.update().
  4982.      His first action is to call super.update, plunging us into
  4983.      Component.update(), which clears the component to the background color,
  4984.      since it has been called on a heavyweight, and returns. Then
  4985.      Container.update() proceeds merrily to call update on all contained
  4986.      Lightweight Components, recursively.
  4987.  
  4988.      The bottom line: "transparency" of lightweight components will only
  4989.      work correctly (without flickering) if the first upwardly accessible
  4990.      heavyweight component in the containment hierarchy is
  4991.         o a double-buffered heavyweight Component (necessarily a Container),
  4992.           or
  4993.         o a heavyweight that never updates, but always paints (i.e. one that
  4994.           has overriden the default update() mechanism to not clear the
  4995.           background).
  4996.      If this is not done, the default Component update() will always clear
  4997.      the background before any repainting is done, leading to annoying
  4998.      flickering.
  4999.  
  5000.      Another important point is that if your Container has its own paint()
  5001.      method, that paint method of the container must call
  5002.      super.update/paint(), otherwise the contained lightweight components
  5003.      will never be painted. Putting this all together, the minimal
  5004.      alteration to code to cause it to work in this case is to place the
  5005.      method
  5006.  
  5007.      public void update(Graphics g) {
  5008.          super.paint(g);
  5009.      }
  5010.  
  5011.      in the most closely containing heavyweight Container, in a Component
  5012.      hierarchy where you want to smoothly render lightweights that do not
  5013.      paint areas extending past that painted by their parents, i.e. ones
  5014.      that are not "transparent". This is dirty, but quick.
  5015.  
  5016.      If you want smooth transparency, the call above should read
  5017.  
  5018.  
  5019.        public void update(Graphics g) {
  5020.          // standard offscreen generation here.
  5021.          offg.fillRect(required background colour, full size);
  5022.          super.paint(offg);
  5023.          g.drawImage(offg, 0, 0, null);
  5024.          }
  5025.  
  5026.        public void paint(Graphics g) {
  5027.          // can generally expect resizes will hit update() first.
  5028.          super.paint(offg);
  5029.          g.drawImage(offg, 0, 0, null);
  5030.          }
  5031.  
  5032.      It's possible to intertwine these, by having this.update() calling
  5033.      this.paint(), with various replacings of the argument, but it is
  5034.      clearest to override them separately, like this.
  5035.  
  5036.  30. (Sect. 10) What is the difference between Component's
  5037.      setForeground(Color c) and Graphics's setColor(Color c) ?
  5038.  
  5039.      [*] First of all, these methods do the same thing: Set the foreground
  5040.      color to the value of the parameter. The difference lies in where you
  5041.      use them. There is also a Component.setBackground that will set the
  5042.      background color.
  5043.  
  5044.      If you are in a constructor or an event handler (e.g. "click here to
  5045.      turn the canvas blue") you have a Component and should use the
  5046.      setForeground() method. If you are in a paint() method, that takes a
  5047.      Graphics context as its argument so you will typically use
  5048.      g.setColor(c).
  5049.  
  5050.      Unlike a Component, a Graphics object doesn't have a background color
  5051.      and a foreground color that you can change independently. A Graphics
  5052.      object arrives in the color(s) inherited from the drawing surface. From
  5053.      then on, any rendering (drawLine(), drawRect(), fillOval(), etc.) will
  5054.      be done in the setColor() color. Because they do different things, the
  5055.      Component and Graphics methods have different names.
  5056.  
  5057.  31. (Sect. 10) When I start a mouse drag inside a Component, and go outside
  5058.      the Component, still dragging, the mouse events still get sent to the
  5059.      Component, even though I am outside it. Is this a bug?
  5060.  
  5061.      [*] No, it is the specified behavior. The Java API documentation says:
  5062.           "... Mouse drag events continue to get sent to this component even
  5063.           when the mouse has left the bounds of the component. The drag
  5064.           events continue until a mouse up event occurs...."
  5065.      It is done for the convenience and ease of the application programmer.
  5066.      It allows you to handle all drags from the place of origin. If you
  5067.      don't want this, simply look at the coordinates of the mouseDrag Event,
  5068.      and if they are outside the Component, ignore them.
  5069.  
  5070.  32. (Sect. 10) Why doesn't my window close when I click on the X in the
  5071.      title bar?
  5072.  
  5073.      [*] Here's how to make your program do that.
  5074.         o JDK 1.0.2: Handle Event.WINDOW_DESTROY to do a hide() and
  5075.           dispose() on the Frame.
  5076.         o JDK 1.1:
  5077.              + Listen for WindowEvent and do hide(); dispose(); in
  5078.                windowClosing() - this really ought to be the "default"
  5079.                behaviour, so was made so for a Swing JFrame.
  5080.              + Enable AWTEvent.WINDOW_CLOSING and do the hide() and
  5081.                dispose() in processWindowEvent().
  5082.         o JDK 1.2: The Component JFrame does a close by default (see section
  5083.           10).
  5084.  
  5085.  33. (Sect. 10) How can I force a synchronization of the graphics state,
  5086.      e.g. of a cursor change, or an animation frame to be rendered?
  5087.  
  5088.      [*] This is done by the sync() method in Toolkit. So just use:
  5089.  
  5090.      AnyComponent.getToolkit().sync();
  5091.  
  5092.  34. (Sect. 10) How can I tab between components?
  5093.  
  5094.      [*] In JDK 1.0, you have to read the key press, and program it
  5095.      explicitly. JDK 1.1 supports tab and shift-tab (previous field)
  5096.      automatically. The tab order is the order that the components were
  5097.      added to the container.
  5098.  
  5099.  35. (Sect. 10) What is the difference between "low level" and "semantic"
  5100.      events?
  5101.  
  5102.      [*] Low-level events are tied to a specific component (resizing a
  5103.      window, dragging the mouse, striking a key, adding a Component to a
  5104.      Container, etc.). Semantic events are those generated when you frob a
  5105.      control (move a scrollbar, click on a button, select from a menu,
  5106.      etc.), and the same kind of event can be generated by several different
  5107.      components. A Button and a List both fire an Action event when they are
  5108.      clicked on.
  5109.  
  5110.      To the programmer, the important difference is that you can change a
  5111.      low-level event such as the key value in a keypress, and it will
  5112.      display the new value. You can also consume low level events so that
  5113.      they do not appear in the widget. You can't do these things with
  5114.      semantic events - they have already "occurred" to the widget.
  5115.  
  5116.      Semantic events: Use the method addXListener() to add a listener object
  5117.      which implements the XListener interface to get XEvent objects
  5118.      delivered (usually via the AWTEventMulticaster). Low level events: Use
  5119.      the method enableEvents() and override performX() to grab those events
  5120.      in the object itself.
  5121.  
  5122.  36. (Sect. 10) Is it possible to have a Java window float above all other
  5123.      windows. For example, a tool palette floats in a super-layer always
  5124.      above all the regular document windows on which you use the palette's
  5125.      tools?
  5126.  
  5127.      [*] On MS Windows, a Window object floats above all other windows,
  5128.      unlike a Frame, which is layered in with ordinary windows. This
  5129.      behavior yields a "floating" effect. Whether a Window object is really
  5130.      supposed to float is another question entirely.
  5131.  
  5132.      On Mac, a Window object is either layered in with other windows, just
  5133.      like a Frame is, or else it is entirely modal - depending on which VM
  5134.      you use. In Java - there appears to be no easy way to get floating
  5135.      behavior. If anyone knows otherwise, please send in your comments.
  5136.  
  5137.  37. (Sect. 10) How can iconify/deiconify a window in Java?
  5138.  
  5139.      [*] There is no way in Java today to write code to force a window to
  5140.      iconify or deiconify. There is a way (tested on Windows and UNIX) to
  5141.      achieve this effect that involves creating and destroying peers, but it
  5142.      is not recommended. You can drop into native code to do it. The "party
  5143.      line" in JavaSoft is that it is because Java is an application
  5144.      language, not a window manager. Everyone wishes they'd add it.
  5145.  
  5146.  38. (Sect. 10) How do I know which mouse button was pressed, and how often?
  5147.  
  5148.      [*] To handle mouse events you have to implement the MouseListener
  5149.      interface, or derive from the MouseAdapter class in order to use one of
  5150.      the mouse-handling methods. The MouseEvent argument passed to the
  5151.      handling methods contains fields that say which button was pressed, and
  5152.      the click count. Use code like this.
  5153.  
  5154.      public void mouseClicked(MouseEvent m) {
  5155.       boolean leftButtonPush   =
  5156.          (m.getModifiers() & java.awt.event.InputEvent.BUTTON1_MASK) != 0;
  5157.       boolean centerButtonPush =
  5158.          (m.getModifiers() & java.awt.event.InputEvent.BUTTON2_MASK) != 0;
  5159.       boolean rightButtonPush  =
  5160.          (m.getModifiers() & java.awt.event.InputEvent.BUTTON3_MASK) != 0;
  5161.  
  5162.       int click = m.getClickCount();    // might be 1,2,3 clicks or more
  5163.  
  5164.      You can also call at m.isPopupTrigger(). If it returns a true value,
  5165.      the user has asked for a pop-up menu. On a lot of window systems, the
  5166.      right mouse button is the trigger for pop-up menus.
  5167.  
  5168.      You can overload processMouseEvent for your component.
  5169.  
  5170.      public void processMouseEvent(MouseEvent e) {
  5171.          if (e.isPopupTrigger())  {
  5172.             // do what you want
  5173.          }
  5174.          else
  5175.            super.processMouseEvent(e);
  5176.        }
  5177.  
  5178.      The code above applies to JDK 1.1. You can also call
  5179.      java.awt.swing.SwingUtilities.isRightMouseButton(MouseEvent me).
  5180.  
  5181.      See also question 15.10.
  5182.  
  5183.                        -------------------------------
  5184.  
  5185. 11. Swing
  5186.  
  5187.   1. (Sect. 11) What is Swing?
  5188.  
  5189.      [*] Swing is a new GUI toolkit bundled with JDK 1.2, and available as
  5190.      an add-on extension library for JDK 1.1. Swing is part of the Java
  5191.      Foundation Classes and supports a GUI toolkit that lets developers
  5192.      create components that have a pluggable look-and-feel. From an
  5193.      architectural standpoint, the Swing component set extends - but does
  5194.      not completely replace - the Abstract Windowing Toolkit (AWT).
  5195.  
  5196.      Swing has many components that can be used in place of components in
  5197.      the AWT (e.g. JFrame instead of Frame, JButton instead of Button,
  5198.      JApplet instead of Applet, JPanel instead of Panel). It also has many
  5199.      components that don't exist in the AWT (e.g. tool tips, toolbars, and
  5200.      progress bars). However Swing relies on the underlying AWT being there.
  5201.  
  5202.      The Swing toolkit allows the creation of GUI's that are every bit as
  5203.      sophisticated as native code toolkits like MFC -- with the Java
  5204.      advantage that they run on every platform. The pluggable look and feel
  5205.      means that they can have the same appearance on every platform, or you
  5206.      can choose to have it look like Windows on a PC, like Motif on a Unix
  5207.      box, etc, just as the user chooses.
  5208.  
  5209.      With Swing, native window behavior is confined to external window
  5210.      frames (and their borders) and a few other things such as fonts and the
  5211.      buffers used to hold window contents. The composition, layout, and
  5212.      drawing of controls is now all handled by Java code. So identical code
  5213.      is executed to create and manage your user interface on every platform.
  5214.      Swing provides a much greater consistency of behavior across different
  5215.      platforms.
  5216.  
  5217.      Swing works with JDK 1.1 if you download the swing.jar file and add it
  5218.      to your path. Swing is built in to JDK 1.2, and Javasoft has just
  5219.      changed its 1.2 Swing package-naming strategy. It is now called
  5220.      javax.swing.
  5221.  
  5222.   2. (Sect. 11) Should I use Swing or AWT to build my GUIs?
  5223.  
  5224.      [*] Use Swing to build your apps now instead of AWT components,
  5225.      wherever you have a choice. Swing is a GUI toolkit that is at least as
  5226.      good as other commercial GUI toolkits, and better in several respects.
  5227.  
  5228.      With Swing, it is easier to build an application that is portable
  5229.      between Mac, Solaris, Windows 95 and NT, than it is to use Win32 and
  5230.      build an application that just runs on Windows 95 and NT.
  5231.  
  5232.   3. (Sect. 11) Where can I find a Swing tutorial?
  5233.  
  5234.      [*] There is a Swing tutorial at
  5235.      http://java.sun.com/docs/books/tutorial/ui/swing/index.html which is
  5236.      part of this tutorial:
  5237.      http://java.sun.com/docs/books/tutorial/ui/TOC.html
  5238.      There is also a Swing FAQ at http://users.vnet.net/wwake/swing/faq.txt
  5239.      Please let this FAQ maintainer know about other good Swing tutorials
  5240.      and online resources.
  5241.  
  5242.   4. (Sect. 11) What is the Model/View/Controller paradigm?
  5243.  
  5244.      [*] Model/View/Controller is a design pattern or framework originally
  5245.      developed by Prof. Trygve Reenskaug at Xerox PARC in 1978/9. MVC was
  5246.      developed to allow Smalltalk to conveniently support GUIs.
  5247.  
  5248.      Model/View/Controller is a design pattern used extensively in Swing.
  5249.      Basically, the "model" contains your data, the "view" is the graphical
  5250.      representation, and the "controller" is responsible for the interaction
  5251.      between the other two. As an example, think of visually editing the
  5252.      Tree widget that represents a directory. The display is the view.
  5253.      Selecting a file, and dragging it to the trash can will delete the
  5254.      file. In order for the delete to happen, the controller must tell the
  5255.      model what just happened in the view.
  5256.  
  5257.      In practice, inter-communication between the view and the controller is
  5258.      complex, so the two are bundled together in one category in Swing. The
  5259.      model (data) is separate though.
  5260.  
  5261.      There's a reasonable white paper on MVC in Swing at
  5262.      http://java.sun.com:81/products/jfc/swingdoc-static/swing_arch.html .
  5263.      There is information on other OO design patterns at
  5264.      http://www.parallax.co.uk/cetus/oo_patterns.html.
  5265.  
  5266.   5. (Sect. 11) When I run the Swing demo on Windows 95 I get an error "Out
  5267.      of environment space."
  5268.  
  5269.      [*] That's because you don't have enough space for your DOS
  5270.      environment. You can fix this with:
  5271.         o Right click your MS-DOS Prompt icon or window and choose
  5272.           Properties.
  5273.         o Choose "Memory" and on "Initial Environment", choose 4096 instead
  5274.           of "auto".
  5275.         o Run Swing again, you'll be OK.
  5276.  
  5277.   6. (Sect. 11) How can I run Swing code in a browser?
  5278.  
  5279.      [*] Most current browsers have to be specifically set up to run Swing
  5280.      applets. Read the article at
  5281.      http://www.javasoft.com/products/jfc/swingdoc-current/applets.html for
  5282.      information about this. The article also contains a simple Swing
  5283.      example applet, so you can confirm that that's your problem.
  5284.      Another approach is to use the Java plug-in, which automatically gives
  5285.      a Swing-compatible Java in the browser. See
  5286.      http://java.sun.com/products/jfc/tsc/swingdoc-current/java_plug_in.html
  5287.  
  5288.   7. (Sect. 11) Why is my menu showing up behind other components when I use
  5289.      Swing?
  5290.  
  5291.      [*] The answer relates to lightweight and heavyweight (peer-based)
  5292.      components. There is a good article about it at
  5293.      http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html
  5294.  
  5295.      For those who want the quick fix, and will read the article later,
  5296.      adding the line:
  5297.  
  5298.      com.sun.java.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
  5299.  
  5300.      before you create any menus will probably fix it (even if you're using
  5301.      menus other than JPopupMenu).
  5302.  
  5303.      The summary answer is that a Lightweight component will not appear over
  5304.      a heavyweight component by default.
  5305.  
  5306.   8. (Sect. 11) Why is there no JCanvas? How do I get a lightweight Canvas?
  5307.  
  5308.      [*] Use a JPanel as a Swing replacement for Canvas. All Swing
  5309.      components have a paint(Graphics) routine that you can override, just
  5310.      as you would have with Canvas, (but you probably want to override
  5311.      paintComponent(Graphics) instead, see next question).
  5312.  
  5313.   9. (Sect. 11) Why don't the borders of my Swing components look right when
  5314.      I override paint(Graphics)?
  5315.  
  5316.      [*] Swing splits painting into several different routines:
  5317.         o paintComponent(Graphics),
  5318.         o paintBorder(Graphics),
  5319.         o paintChildren(Graphics)
  5320.      all of which are called from paint(Graphics). If you override paint(),
  5321.      unless you remember to do it, the paintBorder() and paintChildren()
  5322.      won't get done.
  5323.  
  5324.      In most cases, what you really want to do is override paintComponent()
  5325.      instead of paint().
  5326.  
  5327.  10. (Sect. 11) Why does my JFrame go away after I choose system close on
  5328.      the window?
  5329.  
  5330.      [*] Assume that you have a Swing JFrame component, and you handle the
  5331.      windowClosing event, but do nothing in the handler. You will see that
  5332.      the JFrame disappears anyway.
  5333.      The reason is that JFrame's have default handling of the system close
  5334.      operation, separate from the windowClosing event. You have to override
  5335.      that by calling:
  5336.  
  5337.         setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
  5338.  
  5339.      on your JFrame.
  5340.  
  5341.  11. (Sect. 11) Why can I run the Mac Look and Feel only on Mac OS?
  5342.  
  5343.      [*] (This answer comes from the Swing Connection, see
  5344.      http://java.sun.com/products/jfc/tsc/swingdoc-current/911.html).
  5345.      Sun has not determined that it has the right to deliver the Mac look
  5346.      and feel on platforms other than MacOS. If Apple were to confirm Sun's
  5347.      right to deliver this look and feel on other operating systems, Sun
  5348.      would be delighted to remove the lock. To date, Apple has declined to
  5349.      do this.
  5350.  
  5351.      Although you cannot use the new Mac L&F on non-Macintosh platforms,
  5352.      there is a way to examine the source code so developers can use it as
  5353.      an example of how to create a custom L&F. The Mac L&F is distributed in
  5354.      "stuffed-binhexed" format, which is standard for the Macintosh. If you
  5355.      develop on a MS-Windows platform and would like to examine the source
  5356.      code for the Mac L&F then you can do that by downloading and using a
  5357.      program called Aladdin Expander for Windows. You can download Aladdin
  5358.      Expander from this URL: http://www.aladdinsys.com/expander/index.html
  5359.      When you have downloaded Aladdin Expander, you can use it to decode the
  5360.      Mac L&F file posted on the JDC.
  5361.  
  5362.      A recent posting on comp.lang.java.gui suggested the following user
  5363.      workaround:
  5364.  
  5365.      import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
  5366.      class MyOwnWindowsLookAndFeel extends WindowsLookAndFeel {
  5367.          public isSupportedLookAndFeel() { return true; }
  5368.      }
  5369.  
  5370.      The desire on Sun's part to avoid infringing the Windows Look and Feel
  5371.      is also the reason why the JTree uses colored circles (and soon, little
  5372.      circles with a short line coming out of them) for the nodes to indicate
  5373.      whether they are open or not. The Swing team could have used the '+'
  5374.      and '-' as Windows does, or even the triangles that MacOS uses, but
  5375.      decided against it.
  5376.  
  5377.                        -------------------------------
  5378.  
  5379. 12. Browsers
  5380.  
  5381.   1. (Sect. 12) When will my favorite browser support Java 1.1?
  5382.  
  5383.      [*] All popular browsers now have JDK 1.1 support. Netscape
  5384.      Communicator 4.04 plus patch "J" fully supports the features of Java
  5385.      1.1. It was released in December 1997, and is only missing the JavaSoft
  5386.      support for applet signing (Netscape has gone its own way on this). See
  5387.      http://developer.netscape.com/support/faqs/champions/java.html#21
  5388.      If you have Netscape 4.05, and the console says anything other than
  5389.      Java 1.1.5 then you do not have a fully 1.1 compliant Netscape. There
  5390.      is a special preview version available here:
  5391.      http://developer.netscape.com/software/jdk/download.html
  5392.  
  5393.      Netscape badly fumbled its Java support in 1997 as its market was
  5394.      seized by Microsoft. Microsoft is using IE as a strategic tool to
  5395.      deploy what Microsoft employees call "polluted Java". For both of these
  5396.      browsers, the Java Plug-in is a good approach.
  5397.  
  5398.      Sun's HotJava browser fully supports the JDK 1.1 features. People who
  5399.      are obliged to use a browser without standard Java support should use
  5400.      the Java Plug-In. The Java Plug-In substitutes a standard Java virtual
  5401.      machine for the one that shipped with the browser. It allows you to use
  5402.      RMI, JavaBeans components, and Java Foundation Classes in Internet
  5403.      Explorer 3.02, 4.0, and 4.01. The Java Plug-In also works flawlessly
  5404.      with Netscape browsers. You can download the Java Plug-In from
  5405.      http://java.sun.com/products/.
  5406.      Note that you need to change the HTML a little, to ensure that the
  5407.      plug-in JVM is invoked, not the browser JVM. A tool is included to do
  5408.      the changes automatically.
  5409.  
  5410.   2. (Sect. 12) What applet routines get called in various browsers and the
  5411.      plug-in on different browsing actions (back, forward, load, etc)?
  5412.  
  5413.      [*] Java supporter Dave Postill did the work to get this answer.
  5414.      The life cycle of an applet is illustrated by logging calls to init(),
  5415.      start(), stop() and destroy(). Use caution when your applets have
  5416.      threads since in most sample applet code, the stop() method calls stop
  5417.      on any separate threads within the applet, and then sets them to null.
  5418.  
  5419.      This reckless threadicide is because most people think of the stop()
  5420.      method as something called only when the user leaves the page and wants
  5421.      to forget about it. But since Netscape calls stop() when you resize the
  5422.      window, your users would lose the applet's state when they thought they
  5423.      were only making a minor adjustment.
  5424.  
  5425.      See "Java Tip 8: Threads, Netscape, and the resize problem - How to
  5426.      deal with applet resizing in Netscape Navigator", JavaWorld
  5427.      http://www.javaworld.com/javatips/jw-javatip8.html. Sadly the JavaWorld
  5428.      workaround does not completely fix the problem, since it relies on
  5429.      start() being called soon after stop() to identify a resize. However if
  5430.      you minimise the browser it may send a stop() to the Applet and then
  5431.      may not send a start() until the Browser is either restored or
  5432.      maximised. In this case, using the workaround results in the Applet
  5433.      being destroyed following minimising of the Browser - unless the
  5434.      Browser gets un-minimised within the killThreads timeout.
  5435.  
  5436.                Netscape    Netscape    Applet-    Internet    Internet
  5437.                [4.04/JDK   with        Viewer     Explorer 4  Explorer
  5438.                1.1.4]      Plug-In     [JDK       SP1         with Plug-In
  5439.                [4.05/JDK   [4.05/ JDK  1.1.5]     4.72.3110.8 [5.00.0518.10
  5440.                1.1.5]      1.1.5/      [JDK       on NT 4.0   / Plugin 1.1]
  5441.                            Plugin 1.1] 1.1.6]     SP3         on NT 4.0 SP3
  5442.       1. Clear
  5443.       browser  nothing     nothing     nothing    nothing     nothing
  5444.       cache
  5445.                init(),
  5446.       2.       start() or
  5447.       Initial  init(),     init(),     init(),    init(),     init(),
  5448.       load of  start(),    start()     start()    start()     start()
  5449.       .html    stop(),
  5450.                start() [1]
  5451.  
  5452.       3. Back  stop()      stop(),     [4]        stop(),     stop(),
  5453.                            destroy()              destroy()   destroy()
  5454.       4.                   init(),                init(),     init(),
  5455.       Forward  start()     start()     [4]        start()     start()
  5456.                stop(),     stop(),                stop(),     stop(),
  5457.                init(),     init(),                init(),     init(),
  5458.                start()     start()                start()     start()
  5459.       6.
  5460.       <shift>
  5461.       reload   stop(),     stop(),                stop(),     stop(),
  5462.       [NS],    destroy(),  destroy(),  [4]        destroy(),  destroy(),
  5463.       <ctrl>   init(),     init(),                init(),     init(),
  5464.       reload   start()     start()                start()     start()
  5465.       [IE]
  5466.  
  5467.       7. Resizestop(),     [3]         [3]        [3]         [3]
  5468.                start()
  5469.       8.
  5470.       Minimize [2]         [3]         stop()     [2]         [3]
  5471.       9.
  5472.       Restore  [2]         [3]         start()    [2]         [3]
  5473.  
  5474.       10. Exit stop(),     stop(),     stop(),    stop(),     stop(),
  5475.                destroy()   destroy()   destroy()  destroy()   destroy()
  5476.  
  5477.      Notes:
  5478.      [1] Results not repeatable.
  5479.      [2] Not tested.
  5480.      [3] Tested, and found that no logged methods are called.
  5481.      [4] Test not applicable.
  5482.  
  5483.   3. (Sect. 12) Is it possible to set and retrieve cookies from Java, in a
  5484.      manner that is compatible with all browsers supporting cookies?
  5485.  
  5486.      [*] Short answer: no.
  5487.      Longer answer: probably no.
  5488.      Ultimate answer:
  5489.      A cookie is a morsel of tasty data that a server sends back to the
  5490.      client, and can retrieve on demand. It allows the server to retain some
  5491.      state information for each of its clients. The information is typically
  5492.      something like "what pages has the user seen?" or "is this a privileged
  5493.      user?".
  5494.      The DevEdge site on Netscape's home page has a Javascript-Java example
  5495.      on getting cookies. Also
  5496.      http://www.geocities.com/SiliconValley/Vista/1337 has info on
  5497.      connecting an applet with JavaScript functions. It's quite involved.
  5498.      Stick to just Java if you can.
  5499.  
  5500.   4. (Sect. 12) I am developing an applet and testing it in Netscape
  5501.      Navigator. I find that after I recompile, I press reload, clear the
  5502.      caches, retype the URL of the HTML wrapper, and I still have the old
  5503.      version. Why is this?
  5504.  
  5505.      [*] It is because Netscape has completely failed to improve the
  5506.      defective code that does this monstrously wrong thing. It has been like
  5507.      this for many successive releases.
  5508.      Flushing the network cache will make no difference; that isn't where
  5509.      the caching is taking place. Although applets are sometimes "pruned"
  5510.      and their ClassLoaders garbage-collected, this doesn't happen
  5511.      predictably, so restarting Netscape is the only reliable work-around at
  5512.      the moment.
  5513.      A related question is "how do I make the browser reload from a
  5514.      URLConnection instead of just getting the content from the local
  5515.      cache?" The answer is to use
  5516.  
  5517.         java.net.URLConnection.setUseCaches(false)
  5518.  
  5519.      Browsers seem to vary in their conformance to this programmatic
  5520.      request. Netscape caching varies depending on whether a proxy server is
  5521.      in use, and which thread in the applet made the get request.
  5522.  
  5523.   5. (Sect. 12) Why can't Netscape reload the applet when you press the
  5524.      Reload button?
  5525.  
  5526.      [*] For the applet to be reloaded, the new version would have to be
  5527.      loaded in a different ClassLoader. Navigator/Communicator's policy for
  5528.      assigning ClassLoaders to applets doesn't take into account whether a
  5529.      reload has been done (although there is no technical reason why it
  5530.      couldn't).
  5531.      Some versions of Netscape reload the Applet if you use
  5532.      Edit/Preferences/Advanced/Cache to Clear Memory Cache and Clear Disk
  5533.      Cache, then <Shift> while you click on reload.
  5534.      In Explorer, use View/Options/General/Delete Files, then <Control>
  5535.      'Reload' button to reload the page containing the applet.
  5536.  
  5537.      Until they fix it, use the appletviewer to test applets. And send them
  5538.      mail - developers can only fix the bugs they know about.
  5539.  
  5540.   6. (Sect. 12) Should I use Microsoft CAB files or Java JAR files?
  5541.  
  5542.      [*] The question contains its own answer.
  5543.      CAB format is a Microsoft-only format. So do not use it as it destroys
  5544.      software portability.
  5545.      JAR format is the Java standard format, based on PKZIP format including
  5546.      data compression. JARs were introduced with JDK 1.1.
  5547.      See http://www.ibm.com/java/community/viewarchive4.html for more
  5548.      information.
  5549.      You should use the Java standard format JAR (Java Archive) files, not a
  5550.      vendor-specific format. JAR files are not just a Java standard, they
  5551.      are in industry-standard PKZIP format. One reader comments that both
  5552.      formats can be used with this tag:
  5553.           <APPLET NAME=myapplet
  5554.           ARCHIVE="myzip.zip"
  5555.           CODE="com/nnnnn/nnnn/cccccccc.class"
  5556.           WIDTH=n
  5557.           HEIGHT=n>
  5558.           <PARAM NAME="cabbase" VALUE="mycab.cab">
  5559.           </APPLET>
  5560.      IE3 does not support JAR
  5561.      IE4 supports compressed and uncompressed JAR, but not signed JAR
  5562.  
  5563.   7. (Sect. 12) How can I tell the version of Java that my browser supports?
  5564.  
  5565.      [*] See http://java.rrzn.uni-hannover.de/insel/beispiele/vertest.html.
  5566.      This page tells you whether your browser supports JDK 1.1.
  5567.  
  5568.      See http://www.uni-kassel.de/~pfuetz/Properties.html This page tells
  5569.      you which classes you may expect to be present in the browser's
  5570.      runtime.
  5571.  
  5572.                        -------------------------------
  5573.  
  5574. 13. Applets
  5575.  
  5576.   1. (Sect. 13) What is the difference between an application, an applet,
  5577.      and a servlet?
  5578.  
  5579.      [*] An application is a standalone program. An applet is a downloadable
  5580.      program that runs in a web browser. Typically an applet has restricted
  5581.      access to the client system for reasons of security. Other than that it
  5582.      is virtually no different from a regular Java program.
  5583.      A servlet is a Java program whose input comes from a server and whose
  5584.      output goes to a server. Other than that it is virtually no different
  5585.      from a regular Java program. Think of a servlet as an application, but
  5586.      one that (like an applet) requires a context in which to run, namely
  5587.      web server software. Servlets are used like CGI scripts, and they allow
  5588.      the server end to be written in Java as well as the client. There is a
  5589.      page with much servlet information at:
  5590.      http://www.frontiernet.net/~imaging/servlets_intro.html
  5591.      There is a servlet tutorial at
  5592.      http://java.sun.com/docs/books/tutorial/servlets/index.html
  5593.      The web server starts up a servlet when the URL is referenced, and now
  5594.      your applets have something that they can talk to (via sockets) on the
  5595.      server that can write files, open connections to other servers, or
  5596.      whatever.
  5597.      There is also a software technology from IBM called an "Aglet". An
  5598.      aglet is a mobile agent that can go from machine to machine, performing
  5599.      tasks, serializing data collected, and "shipping itself" (code and
  5600.      data) to the next machine. It's too early to say if aglets are a flash
  5601.      in the pan or a dawning technology. Read about aglets at
  5602.      http://www.trl.ibm.co.jp/aglets/
  5603.      Finally, there is the ticklet (Tcl/Tk) plugin for your browser
  5604.      (Netscape or Explorer) available at http://sunscript.sun.com/plugin/
  5605.      Don't confuse Sun's JWS "Java Web Server" with JWS "Java Workshop".
  5606.      Java Web Server supports servlets, as does the lightweight and free
  5607.      server at Acme.com:
  5608.      http://www.acme.com/java/software/Acme.Serve.Serve.html
  5609.  
  5610.   2. (Sect. 13) My applet works on my machine, but fails when I put it on
  5611.      our web server. Why?
  5612.  
  5613.      [*] It could be one of several reasons, and unfortunately the messages
  5614.      that you get in this situation aren't much help. In general, you can
  5615.      assume that either your applet's class files are corrupted somehow, or
  5616.      the web server can't find one or more of them when the browser needs
  5617.      them.
  5618.      Be careful of the following things:
  5619.         o Make sure you transfer the class files in binary mode, rather than
  5620.           text or ASCII mode. An error from the browser saying "cannot start
  5621.           applet ... bad magic number" usually means that one of the class
  5622.           files on the server is corrupted. Replace your class binary files
  5623.           on the web server, clean up the cache of your browser, and reload
  5624.           your applet.
  5625.         o Make sure you transfer all of the class files that are a part of
  5626.           your applet. Sometimes people are surprised by how many there are.
  5627.           There will be a class file for every class and interface you
  5628.           define, even if you define more than one in a single source file.
  5629.           If you use the Java 1.1 "inner classes" feature, there will be
  5630.           class files for each inner class as well.
  5631.         o Make sure you maintain the appropriate case distinctions in your
  5632.           filenames. If a class is called StUdLy, it must be found in a file
  5633.           called StUdLy.class.
  5634.         o Make sure you maintain the directory structure that matches your
  5635.           package structure. If you declare a class in package com.foo.util,
  5636.           the class either needs to be in a Jar file, or the class file
  5637.           needs to be in directory com/foo/util under the applet's codebase
  5638.           directory. Again, case distinctions are important for
  5639.           package/directory names, just as they are for class/file names.
  5640.         o Make sure that the web server process will have read access to the
  5641.           class files, and search access to the directories that the files
  5642.           are in. For example, if the web server runs on a Unix machine, use
  5643.           the command "chmod o+r filename" for the files, and "chmod o+x
  5644.           dirname" for the directories.
  5645.  
  5646.   3. (Sect. 13) How do I load a webpage using an applet?
  5647.  
  5648.      [*] Use code like this,
  5649.  
  5650.      getAppletContext().showDocument(
  5651.                     new URL("http://www.here.com") );
  5652.  
  5653.      Or, to show the page in another window or frame,
  5654.  
  5655.      getAppletContext().showDocument(
  5656.              new URL("http://www.here.com"), "windowname" );
  5657.  
  5658.   4. (Sect. 13) How do I use an image as the background to my applet? How do
  5659.      I set the background color of my applet the same as the browser?
  5660.  
  5661.      [*] You can simply do a g.drawImage(yourImage, x, y, this) in the
  5662.      paint() routine of your applet. If the image isn't big enough to fill
  5663.      the entire background, tile it or scale it. Here is some code to tile
  5664.      it
  5665.  
  5666.          // The background image is named "bg".
  5667.          int w = 0, h = 0;
  5668.          while (w < size().width) {
  5669.              g.drawImage(bg, w, h, this);
  5670.              while ((h + bg.getHeight(this)) < size().height) {
  5671.                  h += bg.getHeight(this);
  5672.                  g.drawImage(bg, w, h, this);
  5673.              }
  5674.              h = 0;
  5675.              w += bg.getWidth(this);
  5676.          }
  5677.  
  5678.      Alternatively, the AWT can scale your background image to the size of
  5679.      the applet. The result quality will depend on the kind of image. Inside
  5680.      an applet class, you can use:
  5681.  
  5682.         drawImage(img, 0, 0, size().width, size().height, this);
  5683.  
  5684.      You can set the background color to match the background color of the
  5685.      browser by passing the value in as a parameter, like this:
  5686.           In the HTML applet tag:
  5687.                <param name=BrowserColor value=F1F1F1>
  5688.                (value should be the same hex as the HTML COLOR value).
  5689.           In the Applet init() method:
  5690.  
  5691.               String colparam = getParameter("BrowserColor");
  5692.               int col = Integer.valueOf(colparam,16).intValue();
  5693.               setBackground( new Color(col) );
  5694.  
  5695.      An applet cannot override the size imposed by the HTML. If you make the
  5696.      applet larger, the browser will still clip to the original size. If you
  5697.      need more room, open up a new Frame, Window or Dialog to show your
  5698.      output.
  5699.  
  5700.   5. (Sect. 13) How do you make the applet's background transparent?
  5701.  
  5702.      [*] There is no way to give an applet a transparent background that
  5703.      lets the web browser background show through. You can simulate it by
  5704.      giving the applet a background that matches the underlying browser
  5705.      background. It doesn't produce satisfactory results with a patterned
  5706.      background because of problems aligning the edges.
  5707.      Lightweight components (new in JDK 1.1) have a transparent background,
  5708.      but that merely allows other components to show through. A lightweight
  5709.      component is always ultimately positioned in a heavyweight component.
  5710.  
  5711.   6. (Sect. 13) How do you do file I/O from an applet?
  5712.  
  5713.      [*] See answer to question 7.8.
  5714.  
  5715.   7. (Sect. 13) How do you get a Menubar/Menu in an applet?
  5716.  
  5717.      [*] In your applet's init() method, create a Frame instance and then
  5718.      attach the Menus, Menubar etc to that frame. You cannot attach the Menu
  5719.      or a Menubar to an applet directly.
  5720.      Or get the parent Frame like this (doesn't work in all execution
  5721.      environments):
  5722.  
  5723.          Container parent = getParent();
  5724.          while (! (parent instanceof Frame) )
  5725.              parent = parent.getParent();
  5726.          Frame theFrame = (Frame) parent;
  5727.  
  5728.      This second suggestion definitely doesn't work in the appletviewer, and
  5729.      probably won't work on Macs (where would the Menubar go?) or in some
  5730.      browsers. In JDK 1.1, just use a popup menu, which isn't attached to a
  5731.      Frame.
  5732.  
  5733.   8. (Sect. 13) Can I get rid of the message "Warning:Applet Window" along
  5734.      the bottom of my popup windows in my Applet?
  5735.  
  5736.      [*] This is a security feature that prevents the applet programmer from
  5737.      popping up a window that looks like it came from the native OS and
  5738.      asking for passwords or credit card info (etc.). Users must always be
  5739.      aware of when they are talking to an unsigned applet. You can get rid
  5740.      of it by signing the applet, if the user accepts signed applets from
  5741.      you. See the Java Signing FAQ at
  5742.      http://www.fastlane.net/~tlandry/javafaq.txt
  5743.      In Netscape (only), using the Capabilities API to make the call
  5744.  
  5745.         PrivilegeManager.enablePrivilege("UniversalTopLevelWindow");
  5746.  
  5747.      before creating the Frame eliminates the message, if the security
  5748.      manager passes it.
  5749.  
  5750.   9. (Sect. 13) When I subclass Applet, why should I put setup code in the
  5751.      init() method? Why not just a constructor for my class?
  5752.  
  5753.      [*] The browser invokes your constructor, then setStub, then init().
  5754.      Hence when your constructor is invoked, the AppletStub (and through it
  5755.      the AppletContext) is not yet available. Although in principle you can
  5756.      do things in the constructor that don't rely (even indirectly) on the
  5757.      AppletStub or AppletContext, it is less error-prone to simply defer all
  5758.      setup to the init() method. That way you know that anything that needs
  5759.      the stub/context will have it available.
  5760.  
  5761.  10. (Sect. 13) How do I pull a non-class file, such as a .gif, out of a jar
  5762.      file?
  5763.  
  5764.      [*] In your class, you should be able to do something like this:
  5765.  
  5766.          String imageFileName = "foo.jpg"
  5767.          URL imageURL = getClass().getResource(imageFileName);
  5768.          Toolkit tk = Toolkit.getDefaultToolkit();
  5769.          Image img = null;
  5770.          try {
  5771.              java.awt.image.ImageProducer I_P;
  5772.              I_P = (java.awt.image.ImageProducer)imageURL.getContent();
  5773.              img = tk.createImage(I_P);
  5774.  
  5775.      Or equivalently, and possibly simpler, this:
  5776.  
  5777.          String imageFileName = "foo.jpg";
  5778.          InputStream jpgStream = getClass().getResourceAsStream(imageFileName);
  5779.          Toolkit tk = Toolkit.getDefaultToolkit();
  5780.          Image img = null;
  5781.          try {
  5782.              byte imageBytes[]=new byte[jpgStream.available()];
  5783.              jpgStream.read(imageBytes);
  5784.              img = tk.createImage(imageBytes);
  5785.  
  5786.      (Like anything involving Jar files, this is from JDK 1.1 on.)
  5787.      getResource(String) does not work in applets in Netscape
  5788.      due to Netscape security issues. You should use
  5789.      getResourceAsStream(String) there instead.
  5790.      See http://developer.netscape.com/software/jdk/relnotes.htm
  5791.  
  5792.      Note that getResourceAsStream() is also good for reading a text (or
  5793.      other kind of) file from a JAR file.
  5794.  
  5795.         public void init() {
  5796.              InputStream myStream = getClass().getResourceAsStream("myFile");
  5797.              //   ...
  5798.          }
  5799.  
  5800.      Once you have it as an InputStream you can read it how you like.
  5801.  
  5802.  11. (Sect. 13) I want to know about {applets,applications} but the lousy
  5803.      book I got just talks about {applications,applets}. What can I do?
  5804.  
  5805.      [*] The truth is that 95% of the material is the same, whichever your
  5806.      book chooses to focus on. Some people write their apps to work
  5807.      completely in a Panel, then depending on whether they're running
  5808.      stand-alone or in a browser the Panel is either added to a Frame or an
  5809.      Applet. The trick is that you need to add a listener to the
  5810.      application's Frame to handle the WINDOW_CLOSING (previously
  5811.      WINDOW_DESTROY) event yourself.
  5812.      If you fail to do this, when running as an application, the window
  5813.      won't close. See Question 15.7 for a sample of the right handler.
  5814.      In this scenario the following code will tell you which environment
  5815.      you're running in:
  5816.  
  5817.         public boolean isRunningInBrowser() {
  5818.              Component p = getParent();
  5819.              while(p != null && !(p instanceof Frame)) {
  5820.                  p = p.getParent();
  5821.              }
  5822.              return (p == null);
  5823.          }
  5824.  
  5825.  12. (Sect. 13) How do I print a page with an applet?
  5826.  
  5827.      [*] Browsers are starting to introduce support for this. Until they all
  5828.      have it, your best bet is to print a screendump. Using the browser to
  5829.      print the page may leave a blank where the applet is. Putting print
  5830.      support in the applet will print the applet only, not the rest of the
  5831.      browser page.
  5832.      Also in the FAQ: Q5.2.
  5833.  
  5834.  13. (Sect. 13) How can I position my dialogs centered (not top left)?
  5835.  
  5836.      [*] Use some code like this:
  5837.  
  5838.          void center(Component parent) {
  5839.              pack();
  5840.              Point p = parent.getLocation();
  5841.              Dimension d = parent.getSize();
  5842.              Dimension s = getSize();
  5843.              p.translate((d.width - s.width) / 2, (d.height - s.height) / 2);
  5844.              setLocation(p);
  5845.          }
  5846.  
  5847.  14. (Sect. 13) How can I get two applets on the same page to communicate
  5848.      with each other?
  5849.  
  5850.      [*] This is the purpose of the InfoBus protocol. See
  5851.      http://java.sun.com/beans/infobus/index.html
  5852.  
  5853.      The older way to do it was as follows. In your HTML page, give a NAME
  5854.      in the APPLET tag for the applet receiving the message, say <APPLET ...
  5855.      NAME=someName ...>. In the Java code of the other applet do
  5856.  
  5857.          Applet anotherApplet = getAppletContext.getApplet("someName");
  5858.  
  5859.      Cast anotherApplet to the correct applet subclass, and you can call any
  5860.      methods in the applet subclass. Don't forget to use appropriate
  5861.      synchronization when two threads tweak variables. This only works when
  5862.      the applets are truly on the same page. If they are in different
  5863.      frames, it doesn't work.
  5864.      You can walk through all the applets on an HTML page using code like
  5865.      that below. However this appears to be broken in Communicator 4.04 on
  5866.      Win95.
  5867.  
  5868.      Applet otherApplet;
  5869.      AppletContext ac =getAppletContext;
  5870.      Enumeration applets = null;
  5871.      for (applets=ac.getApplets(); applets.hasMoreElements(); ) {
  5872.          otherApplet=(Applet)applets.nextElement();
  5873.          if (otherApplet!=this) break;
  5874.          // do something with otherApplet, e.g.
  5875.          // if (otherApplet instanceof FooApplet) ...
  5876.      }
  5877.  
  5878.      Some people suggest using the static members of a common class to
  5879.      communicate information between the applets. This is not recommended as
  5880.      it relies on class-loading behavior that may change in future. Netscape
  5881.      changed it in one Beta so it didn't work, then changed it back again so
  5882.      it did. It doesn't work if you use the "mayscript" tag though.
  5883.      Inter-applet communication sometimes arises when you have a
  5884.      multi-screen type program and you don't want to force the user into
  5885.      downloading everything at once. One alternative is to make them into
  5886.      one applet with two GUIs. Try to avoid the need for applets to talk to
  5887.      each other. Also check the URL
  5888.      http://java.sun.com:81/products/hotjava/1.1/applet_environment.html
  5889.      which explains how it can be done in HotJava 1.1. Recommendation: avoid
  5890.      code which is browser-specific.
  5891.  
  5892.  15. (Sect. 12) How can I resize an applet?
  5893.  
  5894.      [*] If you want resizing behavior from an applet, you should launch an
  5895.      external Frame that can be resized independently.
  5896.      One programmer suggests using percentages for the height/width
  5897.      parameters in an applet tag, like this:
  5898.  
  5899.          <APPLET CODE="lewinsky.class" WIDTH="100%" HEIGHT="100%">
  5900.  
  5901.  
  5902.      You can't resize the applet directly, but it does get resized when you
  5903.      resize the browser window (tested with Netscape 3.04 and 4.04, but does
  5904.      not work with appletviewer). If you have nothing else on your HTML page
  5905.      and use 100% for your width and height, the browser window looks almost
  5906.      like a real application.
  5907.      For the extremely tricky: have the browser reload the page with the
  5908.      applet when the browser resizes using new values for width and height
  5909.      (probably not what you want most of the time). You would need
  5910.      Javascript to generate a page dynamically using document.write("...")
  5911.      when the browser resizes. Not recommended. Another possibility is to
  5912.      use the new SplitPane class in JFC.
  5913.  
  5914.  16. (Sect. 13) How do I read a text file stored in a JAR?
  5915.  
  5916.      [*] The best way to do this is to use the method
  5917.      Class.getResourceAsStream() which will give you an input stream from
  5918.      which you can read the text file in the JAR. This technique can be used
  5919.      to get parameter info from a text file for an applet.
  5920.      Other sites: See http://www.uq.net.au/~zzcmumme for an example.
  5921.  
  5922.                        -------------------------------
  5923.  
  5924. 14. Multi-Media
  5925.  
  5926.   1. (Sect. 14) Are there any good Java Image libraries?
  5927.  
  5928.      [*] Yes. Try the Java Image Management Interface (JIMI), which offers a
  5929.      free trial period. JIMI is a toolkit that lets your Java programs read
  5930.      and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
  5931.      written in 100% Java, and best of all, it's a breeze to get started
  5932.      with. See http://www.activated.com/jimi.html
  5933.  
  5934.   2. (Sect. 14) Why won't my audio file play?
  5935.  
  5936.      [*] Java 1.1 and earlier releases use one audio format exclusively. The
  5937.      audio file must be in .au format, recorded at 8 KHz, mono, in mu-law
  5938.      encoding. If your audio clip is in a different format (e.g., .wav) or a
  5939.      different frequency it must be converted to the exact specifications
  5940.      above before Java can play it. Support for .wav and other formats is
  5941.      part of the Java Media Framework coming in JDK 1.2.
  5942.      Search at http://www.yahoo.com for GoldWave for Win 95, sox for Unix
  5943.      and similar conversion utilities for other systems.
  5944.      Other sites:
  5945.         o One conversion utility in Java is at
  5946.           http://saturn.math.uaa.alaska.edu/~hursha
  5947.         o The source of a Java class to play linear PCM .WAV files is at:
  5948.           http://www.shef.ac.uk/~cs1mjp/Java/WhiteBoard/WavePlayer.html. It
  5949.           can be used in any Java application or applet.
  5950.  
  5951.   3. (Sect. 14) How can I do video streaming using Java?
  5952.  
  5953.      [*] That is the purpose of StreamBean. See
  5954.      http://www.streambean.com/streambean/
  5955.  
  5956.   4. (Sect. 14) Does Java support animated GIFs?
  5957.  
  5958.      [*] Java 1.0.2 and earlier releases use GIF and JPEG formats, and do
  5959.      not use the GIF89 animated GIF format. (An animated GIF is one that
  5960.      contains successive frames of an image, so when they are displayed in
  5961.      quick sequence the image appears to contain movement). When you display
  5962.      an animated GIF in Java 1.0.2, you will just get the first frame. There
  5963.      doesn't appear to be any easy way to get other frames from the image.
  5964.      The advantage of an animated GIF file is that there is only one file to
  5965.      download, and it is simple to do simple animations. The advantage of
  5966.      programmatic control over individual frames is that you control the
  5967.      rate and order of displaying them.
  5968.      Here's a surprise: JDK 1.1 supports the animated display of animated
  5969.      GIFs. For simple animations animated GIFs are a lot easier and
  5970.      lighter-weight than coding an animation explicitly.
  5971.  
  5972.   5. (Sect. 14) How do I create animated GIFs?
  5973.  
  5974.      [*] Use GIFanimator from ULead (said to be the best)
  5975.      http://www.ulead.com, or GIF Construction Set from Alchemy Mindworks
  5976.  
  5977.   6. (Sect. 14) How do I prevent animated GIFs from flashing while
  5978.      displaying?
  5979.  
  5980.      [*] The problem is most likely that in your paint method you have
  5981.  
  5982.          g.drawImage(img, ix, iy, this);
  5983.  
  5984.  
  5985.      You should change this to
  5986.  
  5987.          g.drawImage(img, ix, iy, getBackground(), this);
  5988.  
  5989.  
  5990.      This will change all the transparent regions of the image to the
  5991.      background color before painting to the screen. If you paint
  5992.      transparent images directly to the screen they flicker.
  5993.      If that does not solve it then check that imageUpdate is
  5994.  
  5995.      public boolean imageUpdate(Image img, int flags, int x, int y,
  5996.                    int width, int height) {
  5997.              if ((flags & (FRAMEBITS|ALLBITS))!= 0) repaint();
  5998.              return (flags & (ALLBITS|ABORT)) == 0;
  5999.      }
  6000.  
  6001.  
  6002.      update is
  6003.  
  6004.          public void update(Graphics g) { paint(g); }
  6005.  
  6006.  
  6007.      If you have a background Image behind the partly transparent animated
  6008.      GIF you will have to double buffer. You can crop the backgound image so
  6009.      you won't have to double buffer the full app and waste too much memory.
  6010.  
  6011.   7. (Sect. 14) Does Java support transparent GIFs?
  6012.  
  6013.      GIF89a images with a transparent background show up as transparent
  6014.      without further filtering. This has been supported from 1.0 on. Java
  6015.      correctly displays both animated GIFs and transparent GIFs.
  6016.      Even better, you can fill the transparent pixels with a color (so they
  6017.      appear non-transparent in Java). Just pass the fill color explicitly:
  6018.  
  6019.          drawImage(img, x, y, w, h, fillcolor, this);
  6020.  
  6021.  
  6022.      Further, you can filter the pixels of an Image to turn any bits you
  6023.      wish transparent. However, the most you can do is reveal what is
  6024.      underneath the image. You cannot reveal what is underneath the applet
  6025.      (i.e. on the browser itself). By default applets have a plain grey
  6026.      background.
  6027.  
  6028.   8. (Sect. 14) How do I play video in Java?
  6029.  
  6030.      [*] Use the Java Media Framework Player API.
  6031.      Other sites:
  6032.         o The Java Media Framework Player API spec can be found at
  6033.           http://java.sun.com/products/java-media/jmf/
  6034.         o Intel has released a SDK for the Java Media Framework Player API.
  6035.           The SDK is for Windows 95 and Windows NT. For more information,
  6036.           see http://developer.intel.com/ial/jmedia
  6037.         o SGI has released an implementation of JMF for IRIX: See
  6038.           http://www.sgi.com/Products/motion/
  6039.  
  6040.   9. (Sect. 14) How can I play *.au files from an application?
  6041.  
  6042.      [*] A new static method was introduced in JDK1.2 in the class Applet:
  6043.  
  6044.          public final static AudioClip newAudioClip(URL url) {
  6045.  
  6046.  
  6047.      The method turns a URL (pointing to an audio file) into an AudioClip.
  6048.      Since the method is static it can be used without any objects of class
  6049.      Applet needing to exist, e.g. in an application. Once you have an
  6050.      AudioClip, you can play it with:
  6051.  
  6052.          MyAudioClip.play();
  6053.  
  6054.  
  6055.      The Java Media Framework provides a richer API for playing sounds in an
  6056.      application.
  6057.      For code prior to JDK 1.2, you can use the AudioClip or AudioPlayer
  6058.      class in sun.audio
  6059.      http://www.javaworld.com/javaworld/javatips/jw-javatip24.html. If you
  6060.      do this your code is no longer 100% pure Java, as it relies on a vendor
  6061.      library.
  6062.  
  6063.          import sun.audio.*;
  6064.  
  6065.  
  6066.          URL url; ...
  6067.          AudioStream audiostream = new AudioStream(url.openStream());
  6068.          AudioPlayer.player.start(audiostream);
  6069.          ...
  6070.          AudioPlayer.player.stop(audiostream);
  6071.  
  6072.  
  6073.      Also in the FAQ:
  6074.      Use the new Java Media Framework API, allowing a wide range of video
  6075.      and audio formats to be played back. See previous question.
  6076.  
  6077.  10. (Sect. 14) How do I read in an image file, in an application?
  6078.  
  6079.      Use
  6080.  
  6081.          Image img = Toolkit.getDefaultToolkit().getImage(fname);
  6082.  
  6083.  
  6084.  11. (Sect. 14) When I initialize a component,I call MyComponent.getImage()
  6085.      to get its image. createImage() returns null! I know the image works
  6086.      elsewhere. What's wrong?
  6087.  
  6088.      [*] A peer component needs to exist for your component before you can
  6089.      get its image. This is done by the method addNotify() (surely one of
  6090.      the most poorly named methods in all Java -- it doesn't mean "add a
  6091.      Notify". It means "Notify that the Component has been added to a
  6092.      Container". It tells the system, "you need to create the peer for this
  6093.      Component now"). addNotify will be called for you when you add your
  6094.      component to a container.
  6095.      Javasoft notes that most applications do not call addNotify() directly.
  6096.      It is called for you when you add the component to a container. If you
  6097.      have any code that requires peer resources, you can move it into a
  6098.      thread that is started from a conditional branch of the paint() or
  6099.      update() method. That way the peer will definitely exist when the code
  6100.      is executed.
  6101.      A common reason for seeming to require peer resources in a constructor,
  6102.      or alternatively in the getPreferredSize() method, (which is also
  6103.      usually before the peer is created) is to measure the area required for
  6104.      your window, in terms of font and image sizes. Font sizes may be
  6105.      obtained by calling
  6106.      Toolkit.getDefaultToolkit().getFontMetrics(somefont). This does not
  6107.      require a peer. Image sizes may be obtained by waiting for the relevant
  6108.      Image to load from the ImageProducer by using an ImageObserver, or a
  6109.      MediaTracker (see 8.15), also without requiring a peer. See 15.4 for
  6110.      more discussion of this problem.
  6111.      If you override addNotify(), don't forget to call super.addNotify() in
  6112.      your overriding version.
  6113.  
  6114.  12. (Sect. 14) How can I force a reload a fresh version of an image into my
  6115.      applet? My image file is changed periodically, and I want the applet to
  6116.      go and retrieve it, not cache it.
  6117.  
  6118.      [*] You need to turn off caching for the URL.
  6119.  
  6120.      URL url = null;
  6121.      URLConnection con;
  6122.      try {
  6123.       url = new URL(getDocumentBase(),"image.jpg");
  6124.       con = url.openConnection();
  6125.       con.setUseCaches(false);
  6126.      } catch (MalformedURLException e1) {
  6127.             System.err.println(e1.getMessage());}
  6128.        catch (IOException e2) {
  6129.             System.err.println(e2.getMessage());}
  6130.  
  6131.      Note: Some programmers have reported that it caches anyway, even if
  6132.      they do this. That is a browser bug.
  6133.      One programmer reported that even after turning off caching and calling
  6134.      image.flush() before getImage(..), he was still seeing the same picture
  6135.      even though it had been changed on the server.
  6136.      He worked out a solution: access the image via a cgi script that
  6137.      returned a URL. This redirects the browser, and he put in an Expires:
  6138.      header as well to force the reload. Painful and laborious, but it got
  6139.      the result.
  6140.  
  6141.  13. (Sect. 14) How can I save an Image file to disk in JPG or GIF format?
  6142.  
  6143.      [*] A number of people have written utilities to do that. One of them
  6144.      was available at the same place as this FAQ, but has now been removed
  6145.      since it was pointed out that Unisys asserts that it has license
  6146.      control even over freeware GIF writers.
  6147.  
  6148.      Try the Java Image Management Interface (JIMI), which is free for
  6149.      non-commercial use. JIMI is a toolkit that lets your Java programs read
  6150.      and write many graphics file formats (PNG, JPG, BMP, GIF etc). JIMI is
  6151.      written in 100% Java, and best of all, it's a breeze to get started
  6152.      with. See http://www.activated.com/jimi.html
  6153.  
  6154.      Other sites:
  6155.         o Jef Poskanzer has written an abstract ImageEncoder class and
  6156.           implemented it for GIFs and PPMs. Those are at
  6157.           http://www.acme.com/java/software/
  6158.         o A non-Java solution is to use the standard IJG 'cjpeg' utility. It
  6159.           supports GIF, PPM, BMP, PNG and Targa input files.
  6160.         o Hong Shi wrote a PPM to JPEG convertor.
  6161.           http://www.ctr.columbia.edu/~hshi/report6880.htm
  6162.         o Sean Breslin has written a program that compresses a Java Image
  6163.           into a JPEG file. http://www.afu.com/jpeg.txt
  6164.         o Florian Raemy has written a program that encodes a JPEG then
  6165.           decodes it again. http://lcavwww.epfl.ch/demos/jpeg.html This is a
  6166.           proof of concept, not industrial strength code that meets the JFIF
  6167.           (JPEG File Interchange Format) standard.
  6168.  
  6169.  14. (Sect. 14) What causes this problem:
  6170.  
  6171.      $ appletviewer m.html
  6172.      Premature end of JPEG file
  6173.      sun.awt.image.Im...Exception: JPEG datastream contains no image
  6174.      at sun.awt.image. ... .produceImage(JPEGImageDecoder.java:133)
  6175.      at sun.awt.image.Inpu...mageSource.doFetch(
  6176.                                    InputStreamImageSource.java:215)
  6177.      at sun.awt.image.ImageFetcher.run(ImageFetcher.java:98)
  6178.  
  6179.      [*] There's a known bug in early releases of the JDK which can cause
  6180.      the above failure when reading a JPEG across a slow connection. The
  6181.      failure only occurs if the JPEG contains a large application data block
  6182.      (APPn marker) - the problem is that the JPEG decoder is trying to skip
  6183.      over the APPn and failing if not all of the APPn has been received yet.
  6184.      The quoted error message is only one of several possible complaints,
  6185.      but they all stem from the same root.
  6186.      Photoshop is the most common source of JPEGs containing oversize APPn
  6187.      blocks. In particular, if you allow Photoshop 4 to save a thumbnail
  6188.      (preview) in a JPEG, the thumbnail plumps up Photoshop's private APPn
  6189.      marker to several K, which is usually enough to cause this problem.
  6190.      There are several possible workarounds:
  6191.         o Get a newer JDK - this problem is said to be fixed in 1.1. (If you
  6192.           are putting images up on the Web, this isn't much of a solution,
  6193.           because you can't assume visitors to your site have an up-to-date
  6194.           Java installation.)
  6195.         o When making JPEGs for Web use from Photoshop, make sure you have
  6196.           turned off the "save thumbnails" preference. (This is a good idea
  6197.           quite aside from bug workarounds, because the thumbnail is just a
  6198.           waste of download time as far as a Web browser is concerned.) You
  6199.           might still have a problem if you've got verbose comments or lots
  6200.           of paths being saved into the file, but 99% of the time, getting
  6201.           rid of the thumbnail will make Photoshop's APPn small enough to
  6202.           not trigger the Java bug.
  6203.         o Use a tool such as 'jpegtran' (from the Independent JPEG Group) to
  6204.           strip out the Photoshop APPn entirely without any loss of image
  6205.           quality. Recommended answer for the compulsive byte-trimmer.
  6206.         o (Last resort) Load and resave the image in a different image
  6207.           editor that won't insert any APPn or other overhead data. This
  6208.           implies a JPEG generational loss, so I don't recommend it if you
  6209.           are picky about image quality.
  6210.      Any large overhead marker will cause the same problem; 4K of comment
  6211.      text, say, in a COM marker. So Photoshop is not the only source of
  6212.      tickling this bug.
  6213.  
  6214.  15. (Sect. 14) How can I convert between GIF and JPEG formats?
  6215.  
  6216.      [*] In a word: don't.
  6217.      There's hardly any overlap between the set of images that JPEG works
  6218.      well on and the set that GIF works well on. Sometimes, with enough
  6219.      care, you can get an acceptable conversion...but most of the time
  6220.      GIF<->JPEG conversion will just turn your image to mush. It's better to
  6221.      pick the right format in the first place.
  6222.      Other sites:
  6223.         o If you're determined to convert formats anyway, try the GBM
  6224.           (Generalized Bitmap Module). The package is GNU licensed, in C and
  6225.           is very good. Find it at
  6226.           http://www.interalpha.net/customer/nyangau/
  6227.           GBM does a good job converting to JPEG, and 'lossiness' is
  6228.           adjustable to 0%. It also converts to/from about 20 other formats,
  6229.           does cropping, sizing, color mapping, gamma correction,
  6230.           halftoning, everything you could want. GBM source doesn't support
  6231.           JPEG directly, but utilizes JPEG source from IJG called jpeg-6a
  6232.           and found at
  6233.           ftp://sun2.urz.uni-heidelberg.de/pub/simtel/graphics/jpegsr6a.zip
  6234.         o For more info see the JPEG FAQ at
  6235.           http://www.faqs.org/faqs/jpeg-faq/
  6236.  
  6237.  16. (Sect. 14) If you have an InputStream (rather than a file) that
  6238.      contains an Image, how can you display it?
  6239.  
  6240.      [*] Use this method, and some adroit shuffling.
  6241.  
  6242.  
  6243.          Toolkit.getImage(URL url)
  6244.  
  6245.  
  6246.      Create a thread that pretends to be an http server. Make it listen to
  6247.      some port (8765 for example) for incoming requests. When the thread
  6248.      gets a request, it should simply whisk up the appropriate http headers
  6249.      and follow it by the InputStream. Thus the component that has the input
  6250.      stream and wants to do the getImage(url) can now invoke:
  6251.  
  6252.          Toolkit.getImage("localhost:8765/")
  6253.  
  6254.  
  6255.      The thread will act as a stream-to-url adapter, and send back the data
  6256.      It saves you from having to read 200K of JPEG data before you can begin
  6257.      drawing anything.
  6258.  
  6259.  17. (Sect. 14) How can I record sounds in Java?
  6260.  
  6261.      [*] The Java Media Framework will eventually support this, but it does
  6262.      not yet. JMF 1.0.1 only supports playback.
  6263.      JMF 1.0.1 is bundled with JDK 1.2, and available as a separate download
  6264.      for JDK 1.1 and Netscape Communicator 4 with Java 1.1.
  6265.      Other sites:
  6266.           In the meantime, there is a package for Win95/NT available at
  6267.           http://www.scrawl.com/store/. It supports 8, 16-bit, stereo, mono,
  6268.           11025, 22050, 44100 Hz record/play, load/save .WAV files. You
  6269.           could also interface to native code for your platform.
  6270.  
  6271.  18. (Sect. 14) Does Java have any built-in support for displaying HTML?
  6272.  
  6273.      [*] JDK 1.1 supports rendering HTML using the unbundled JFC 1.1 package
  6274.      known as Swing. The Swing package is bundled in JDK 1.2. It has an
  6275.      elementary (graphics, tables, text) HTML bean that is good enough for
  6276.      simple rendering (help files, email, etc).
  6277.      Other sites:
  6278.         o JavaBrowser http://www.ii.uib.no/~alexey/jb/index.html Free
  6279.           source, free for use under GNU LGPL licence, HTML 2.0 (sort of).
  6280.         o ICE Browser - Java Bean Component
  6281.           http://www.icesoft.no/ICEBrowser/ Free binaries for use in free
  6282.           applications. Commercial licensing available including source -
  6283.           flat fee licence. Thin HTML client! Lightweight! HTML 3.2
  6284.         o HotJava HTML Component - Java Bean Component
  6285.           http://www.javasoft.com/products/hotjava/bean/index.html $195 for
  6286.           private use binary licence. HTML 3.2
  6287.         o HTML browser (free source)
  6288.           http://barium.tn.tudelft.nl/people/gool/java/html/Html.html
  6289.         o Web Window Browser http://www.opencube.com/example_wwb.htm $139 -
  6290.           no sources.
  6291.         o jHelp ($20-650) http://w3.nai.net/~rvdi/jhelp/jhelp2/jhelp.html
  6292.           jHelp is a HTML browser component written in Java, HTML 2.0
  6293.  
  6294.  19. (Sect. 14) I loaded an Image file from a JPEG/GIF file using the
  6295.      Toolkit/Applet.createImage(URL/String) method, and (the height and
  6296.      width are -1 / it will not draw to the screen). What is wrong?
  6297.  
  6298.      [*] The behaviour of the AWT on creating images in this way is to do
  6299.      nothing at all.
  6300.      When the image is first drawn using Component.drawImage(), or its size
  6301.      is requested, the image begins to load in a different Thread.
  6302.      As the image loads, the ImageObserver specified in the
  6303.      drawImage()/getHeight() call is periodically notified of the loading
  6304.      status of the image, by calls to its imageUpdate() method.
  6305.      In the case of Component.drawImage() call, the default behavior of
  6306.      Component.imageUpdate() is to schedule *another* repaint() call when
  6307.      the image has fully loaded. This means that, in particular the
  6308.      following code will not work:
  6309.  
  6310.          class MyComponent extends Component {
  6311.            ...
  6312.            public void paint(Graphics g) {
  6313.              ImageFilter cropper=new CropImageFilter(0,0,16,16);
  6314.              Image cropped_image=createImage(new
  6315.              FilteredImageSource(image.getSource(),cropper));
  6316.              g.drawImage(image,10,400,this);        // this line works
  6317.               // this line doesn't -
  6318.              g.drawImage(cropped_image,400,15,this);
  6319.              }
  6320.            }
  6321.  
  6322.  
  6323.      The cropped_image will not be created in time to be painted, and when
  6324.      it is finally created, another call will be scheduled to paint, which
  6325.      will try to draw another one, etc.
  6326.      (Note also that creating objects like this in paint() methods is
  6327.      generally a very poor idea in Java, since they are called very
  6328.      frequently, and you will strongly offend the garbage collector.
  6329.      In order to get round this problem, you may i) add all such Images to a
  6330.      MediaTracker, and call the waitForAll() method. ii) implement your own
  6331.      ImageObserver interface, and wait for the imageUpdate() method to be
  6332.      called with the ALLBITS/FRAMEBITS value. i) is easier, but ii) is
  6333.      recommended, since there are reports of MediaTracker not working in
  6334.      some environments.
  6335.      Also in the FAQ:
  6336.         o See also Q13.12
  6337.         o See Q6.4 for examples of how to reuse objects.
  6338.  
  6339.  20. (Sect. 14) How can I record sound in an applet?
  6340.  
  6341.      [*] If you are using win95/nt, you could use SoundBite - Audio
  6342.      Recording in Applets. See http://www.scrawl.com/store/
  6343.      It provides easy access to audio data in arrays:
  6344.      short[] left, right;
  6345.  
  6346.                        -------------------------------
  6347.  
  6348. 15. Networking and Distributed Objects
  6349.  
  6350.                                     RMI Issues
  6351.  
  6352.   1. (Sect. 15) Should I use CORBA in preference to RMI? Or DCOM? Or what?
  6353.  
  6354.      [*] If your distributed programs are all in Java, then RMI provides a
  6355.      simpler mechanism that allows the transfer of code, pass-by-value of
  6356.      real Java objects, and automatic garbage collection of remote objects.
  6357.      If you need to connect to C++ (or other language) systems or you need
  6358.      CORBA-specific services, then CORBA is your choice.
  6359.      In July 1997, Sun announced that it was aligning RMI to work more
  6360.      closely with CORBA. Sun is simply adding an IIOP transport layer to RMI
  6361.      to support interoperability with CORBA. Java programs can then use RMI
  6362.      to access CORBA-based objects through IIOP, the OMG's CORBA-based
  6363.      protocol. This is very good news for those building heterogenous
  6364.      Enterprise systems, although it will take some additions to IIOP to
  6365.      support the pieces that RMI uses.
  6366.      Microsoft spokespeople have tried to promote DCOM by spreading
  6367.      misinformation that RMI is changing or being dropped. That is totally
  6368.      wrong. The RMI API continues unchanged in its current form. Using DCOM
  6369.      would restrict your code to only ever run on Microsoft platforms using
  6370.      Intel hardware, and negates the "write once, run anywhere" Java
  6371.      philosophy. Non-portable, single vendor code should be avoided.
  6372.      Other sites:
  6373.           http://www.javaworld.com/javaworld/jw-10-1997/jw-10-corbajava.html
  6374.           has a good intro to CORBA in the Java world.
  6375.           http://www.objenv.com/cetus has a CORBA/RMI comparison.
  6376.  
  6377.   2. (Sect. 15) How do I do RMI into a different domain?"
  6378.  
  6379.      [*] Similar to the proxy answer in a section below; you must tell the
  6380.      program where to find the server. In this case start up the client with
  6381.      this commandline option: -Djava.rmi.server.hostname=hostname.domainname
  6382.  
  6383.   3. (Sect. 15) RMI seems to have stopped working for me in JDK 1.1. Why is
  6384.      this?
  6385.  
  6386.      [*] The rules for where the client looks for a stub class seem to have
  6387.      changed making it necessary to reset your class path on the client
  6388.      after starting the RMI registry. In particular, it looks like rmic was
  6389.      not updated to the new "don't need $CLASSPATH" convention as the
  6390.      compiler was.
  6391.      Other sites:
  6392.      There are several very good sources available from Sun which cover many
  6393.      simple and advanced RMI problems.
  6394.         o The documentation, of course:
  6395.           http://java.sun.com/products/jdk/1.1/docs/guide/rmi/index.html
  6396.         o Dedicated FAQs on RMI and Object Serialization
  6397.           http://java.sun.com/products/jdk/rmi/faq.html
  6398.         o Mailing list RMI-USERS@JAVASOFT.COM with archive at
  6399.           http://chatsubo.javasoft.com/email/rmi-users/ Visit the archive!
  6400.  
  6401.   4. (Sect. 15) After a number of RMI client to server connections (55 on my
  6402.      system), subsequent RMI clients trying to connect fail. Why?
  6403.  
  6404.      [*] You are hitting the default limit of 64 open file descriptors. Try
  6405.      increasing the limit in your OS.
  6406.      In addition there is currently a practical RMI connection limit imposed
  6407.      by the scalability of the VM and the performance of object
  6408.      serialization. This is addressed in JDK 1.2. The actual number of
  6409.      active clients you will be able to support will depend on the workload
  6410.      mix you have (i.e. the number of clients, how often they talk to the
  6411.      server, and how much work must be done per call).
  6412.  
  6413.   5. (Sect. 15) I'm using RMI on Win95, and the Naming.lookup() call is
  6414.      taking a long time, even for localhost. How do I fix it?
  6415.  
  6416.      [*] (See also the first answer in next section below) Try adding a
  6417.      definition for the machine in your "hosts" file. Typically, this file
  6418.      will be named c:\windows\hosts (if it doesn't exist, there should be a
  6419.      file called c:\windows\hosts.sam). The hosts file is searched by your
  6420.      TCP/IP stack before it resorts to DNS, so adding an entry in this file
  6421.      can speed up your lookups considerably. The hosts file is used to map
  6422.      IP addresses to symbolic addresses. To enter the name "localhost" with
  6423.      address 127.0.0.1 (the IP loopback address), enter the following line
  6424.      in your hosts file. 127.0.0.1 localhost
  6425.  
  6426.                                 Windows Networking
  6427.  
  6428.   6. (Sect. 15) Why does < Windows RMI/my java debugger/IDE/other> hang for
  6429.      a couple of minutes if my Windows PC is not dialed up to the Internet?
  6430.  
  6431.      [*] Java has networking support built in. When the Java program starts
  6432.      the Winsock DLL automatically gets loaded. The first thing this does is
  6433.      to try to resolve the fully qualified domain name for your machine
  6434.      under the name "localhost". If your system doesn't have this name
  6435.      mapped, it will try to query a nameserver on the internet, which is
  6436.      typically (on a PC) your dialup ISP. So it either prompts you to
  6437.      connect to the ISP, or waits till the attempt times out.
  6438.  
  6439.      You can probably avoid the Win95 problem by giving your system another
  6440.      way to resolve DNS names. Edit the hosts file for your system so that
  6441.      localhost and the full domain name are both mentioned. On Windows 95
  6442.      systems the hosts file is: %windir%\HOSTS (for example,
  6443.      C:\WINDOWS\HOSTS). On Windows NT systems the hosts file is:
  6444.      %windir%\System32\DRIVERS\ETC\HOSTS (for example,
  6445.      C:\WINNT\System32\DRIVERS\ETC\HOSTS).
  6446.      One gotcha under Win95 is that if the last entry in the hosts file is
  6447.      not concluded with a carriage-return/line-feed then the hosts file will
  6448.      not be read at all. So if my system is called goober.best.com change
  6449.      the hosts file from
  6450.  
  6451.  
  6452.              127.0.0.1 localhost
  6453.  
  6454.  
  6455.      to
  6456.  
  6457.              127.0.0.1 goober.best.com localhost
  6458.  
  6459.  
  6460.      Showing more of the file:
  6461.  
  6462.           # Hosts file
  6463.           127.0.0.1       localhost
  6464.           129.146.77.177  goober
  6465.  
  6466.  
  6467.      Another alternative is to dial up with a PPP connection to your ISP
  6468.      whenever you want to run networking programs.
  6469.  
  6470.      Fundamentally the experience of some people has been that networking is
  6471.      not completely satisfactory on Windows95, and is subject to sporadic
  6472.      unexplained failures. If this occurs to you, there is little choice but
  6473.      to reboot and start again.
  6474.      Other sites:
  6475.           Microsoft has several network-related patches at its site
  6476.           http://www.microsoft.com/
  6477.  
  6478.   7. (Sect. 15) I am using JDK 1.1.1 on Windows95, and when I start jdb I
  6479.      get "Uncaught exception: java.lang.UnsatisfiedLinkError no winawt in
  6480.      shared library path". The same program works OK using JDK 1.1.
  6481.  
  6482.      [*] It sounds like your java\bin directory is not on your PATH and so
  6483.      the system can't find the winawt DLL.
  6484.      But actually the problem is the version of Microsoft's Visual C++ that
  6485.      was used to build the product. VC++ 4.2 incorrectly generates code that
  6486.      depends on MSCVRT.DLL or in the case of java_g, MSVCRTD.DLL. These DLLs
  6487.      are not present in (some versions of) Win95. To make things even more
  6488.      interesting, some versions of Win95 (yes, there are at least four
  6489.      different ones...) ship with a broken MSVCRT.DLL (and MSVCRTD.DLL?)
  6490.      that seems to work, only it doesn't, and after a while it dies.
  6491.      Sun linked the winawt_g.dll with VC++ 4.2, which wrongly brought in
  6492.      MSVCRTD.DLL, the debug version of the VC++ runtime. You have to get
  6493.      that library from somewhere (like, say, VC++) in order to get jdb to
  6494.      run.
  6495.      You'll hit this problem any time you try to debug 1.1.1 code with jdb
  6496.      on a win95 system that doesn't have VC++ (or the MSVCRTD.DLL library
  6497.      from some other source) installed. At least this is a problem you can
  6498.      solve without waiting for the next release.
  6499.      Other sites:
  6500.           Some people say that the missing library has been seen at
  6501.           http://cag-www.lcs.mit.edu/curl/Binaries/PC/ Others say you need
  6502.           to buy VC++ to get it.
  6503.  
  6504.                              Other Networking Issues
  6505.  
  6506.   8. (Sect. 15) If I call the InetAddress.getByName() method with an
  6507.      IP-address-string argument, like "192.168.0.1", get an
  6508.      UnknownHostException on some platforms, but not others. Code like
  6509.  
  6510.      Socket sock = new Socket("155.152.5.1", 23);
  6511.  
  6512.      triggers the exception. Why?
  6513.  
  6514.      [*] This is a platform difference that arises out of different
  6515.      semantics in the underlying network libraries, and is [said to be, but
  6516.      subject to confirmation] fixed in JDK 1.1. On Solaris and Windows NT,
  6517.      the IP address string only works for IP addresses that have an
  6518.      associated hostname. On Linux and Windows 95, the IP address string
  6519.      works in all cases.
  6520.      When InetAddress is instantiated with an IP address, a reverse DNS
  6521.      lookup is done. If the IP address is not associated with a valid
  6522.      hostname, the instantiation will fail. This is part of anti
  6523.      DNS-spoofing, and in JDK 1.1 works because the reverse lookup will not
  6524.      occur until the hostname is asked for. So in JDK 1.1,
  6525.  
  6526.              InetAddress in = InetAddress.getByName("155.152.5.1");
  6527.  
  6528.  
  6529.      [Note: this info is still to be confirmed. Net gurus?]
  6530.      Other sites:
  6531.           Microsoft has several network-related patches at its site
  6532.           http://www.microsoft.com/
  6533.  
  6534.   9. (Sect. 15) I want to pass a class file to willing recipients who are
  6535.      using my applet. Any ideas how?
  6536.  
  6537.      [*] You could use a trick: put your .class file(s) in a .zip archive
  6538.      and use showDocument() on the URL. A person accessing this will get a
  6539.      dialog box put up asking them about saving the file to their local hard
  6540.      disk.
  6541.      Other sites:
  6542.           You can see this in action and try it out yourself at:
  6543.           http://www.best.com/~rmlynch/saveit.html
  6544.  
  6545.  10. (Sect. 15) How do I get a URLConnection to work through proxy
  6546.      firewalls? I.e. How do you get your Java application to do its web
  6547.      accesses through a proxy?
  6548.  
  6549.      [*] This is typically needed for any net access to another domain. Tell
  6550.      the run time system what you are trying to do, by using these
  6551.      commandline arguments when you start the program.
  6552.  
  6553.      java -DproxySet=true -DproxyHost=SOMEHOST -DproxyPort=SOMENUM code.java
  6554.  
  6555.      Note proxyPort is optional and it defaults to 80. Without this, you
  6556.      will see an exception like java.net.UnknownHostException or
  6557.      java.net.NoRouteToHostException
  6558.  
  6559.      [It is claimed but not yet confirmed by me that] The proxy settings
  6560.      work for both java.net.URLConnection, and for java.net.Sockets. [help
  6561.      welcome].
  6562.  
  6563.      Netscape's and IE's JVMs (at least in versions 4.x+) take the proxy
  6564.      settings for applets from the browser's proxy configuration. You can
  6565.      also do URL proxies in applications (not applets) with the following
  6566.      code
  6567.  
  6568.  
  6569.          // set up to use proxy
  6570.          System.getProperties().put("proxySet", "true");
  6571.          System.getProperties().put("proxyHost", "myproxy.server.name");
  6572.          System.getProperties().put("proxyPort", "80");
  6573.  
  6574.  
  6575.      But how do I know the name of the proxy server?
  6576.      This code just tells you how you can get a URL connection to the
  6577.      outside. Since it is your proxy server, you are expected to know the
  6578.      name of it. There isn't any code that you can write that will allow
  6579.      arbitrary URL connections to be initiated from outside the firewall.
  6580.      Think about it! If there were, the firewall would not be doing its job.
  6581.  
  6582.      Also note there are corresponding socksProxyPort and socksProxyHost for
  6583.      when socks is used instead of proxy. The default socks port is 1080.
  6584.  
  6585.  11. (Sect. 15) What is "swizzle", as in "Swizzle this object?"
  6586.  
  6587.      [*] It means serialize. To swizzle an object is to recursively
  6588.      serialize or flatten composed objects.
  6589.  
  6590.  12. (Sect. 15) I have been using the Serializing capabilities in 1.1 to
  6591.      save some objects to disk. I added a new field to one of my objects
  6592.      that get serialized and now deserializing my old data no longer works.
  6593.      I get this exception:
  6594.  
  6595.  
  6596.      java.io.InvalidClassException: MacroData; Local class not compatible
  6597.  
  6598.  
  6599.      [*] You need to add a declaration such as
  6600.  
  6601.  
  6602.          static final long serialVersionUID = 4021215565287364875L;
  6603.  
  6604.  
  6605.      in the modified class. The actual value of this long is supplied by the
  6606.      "serialver" utilitity suppied with the JDK. Any versions of a class
  6607.      other than the first version require this static to be defined in the
  6608.      class. This is how versioning is achieved.
  6609.  
  6610.  13. (Sect. 15) My socket code looks good, but is broken!
  6611.  
  6612.      [*] When using sockets you typically open both inward and outward
  6613.      streams. If you close one of them, the other seems to 'break'
  6614.      instantly. Check whether this is happening for you, by adding the
  6615.      matched pair.
  6616.      [comments from net gurus welcome]
  6617.  
  6618.  14. (Sect. 15) How do I map between IP address and hostname?
  6619.  
  6620.      [*] In Java 1.1 (earlier releases were buggy) use:
  6621.  
  6622.  
  6623.          String host = InetAddress.getByName("211.10.2.119").getHostName();
  6624.  
  6625.  
  6626.  15. (Sect. 15) How do I embed an anchor in a URL? Just putting it as part
  6627.      of the string in the constructor doesn't work.
  6628.  
  6629.      [*] Like this:
  6630.  
  6631.  
  6632.          URL url = new URL("http://www.my_domain.com/my_page.html");
  6633.          URL anchor = new URL(url, "#section2");
  6634.          this.getAppletContext().showDocument(anchor);
  6635.  
  6636.  
  6637.  16. (Sect. 15) How do I POST to a CGI script from an applet?
  6638.  
  6639.      [*] Let's start by noting that this is more troublesome than it might
  6640.      seem at first, and that GET is preferred. For an untrusted applet, the
  6641.      CGI script can only be on the server that served the applet. Then use
  6642.      code like this:
  6643.  
  6644.  
  6645.          try { sock = new Socket(host, 80);
  6646.          dock = new DataOutputStream(sock.getOutputStream());
  6647.          dock.writeBytes("POST "+cgiloc+" HTTP/1.0\n");
  6648.          dock.writeBytes("Content-type: text/html\n");
  6649.          dock.writeBytes("Content-length: " +my_string.length() + "\n\n");
  6650.          dock.writeBytes(my_string+"\n");
  6651.          dock.close();
  6652.          sock.close();
  6653.  
  6654.  
  6655.          uresp = new URL(getDocumentBase(),"respond.html");
  6656.          getAppletContext().showDocument(uresp); }
  6657.  
  6658.  
  6659.      The my_string contains the data you want to POST to the CGI script. The
  6660.      string should be encoded in the special way CGI expects. The class
  6661.      method java.net.URLEncoder.encode(my_string) will do it. The CGI has to
  6662.      write its output to respond.html so that it can be displayed by the
  6663.      browser. Even this won't really work, because respond.html could be
  6664.      overwritten by a subsequent request to the same CGI before the results
  6665.      of the first POST are read back.
  6666.      To get an acceptable solution takes quite a lot of effort. In general
  6667.      you should prefer GET to POST for CGI access from Java. As it says on
  6668.      the Javaworld page, the answers to the question are really: you can't,
  6669.      don't POST (use GET), use a bean, or cheat.
  6670.      Finally, if you request a URL via the URLConnection/HttpURLConnection,
  6671.      the server sets the content type, and your applet can use
  6672.      URLConnection.getContentType() to get the type. Alternatively, use
  6673.      setRequestProperty to set it, like this:
  6674.  
  6675.  
  6676.          url = new URL(cgiUrl);
  6677.          urlc = url.openConnection();
  6678.          urlc.setRequestProperty(
  6679.                         "Content-type",
  6680.                         "application/x-www-form-urlencoded");
  6681.  
  6682.  
  6683.      Other sites:
  6684.           There's a pretty good explanation at
  6685.           http://www.javaworld.com/javaworld/javatips/jw-javatip41.html
  6686.  
  6687.  17. (Sect. 15) How can I write CGI programs in Java?
  6688.  
  6689.      [*] CGI (the Common Gateway Interface for web servers) is an API for
  6690.      writing programs that use the web as its user interface. By far, the
  6691.      most popular language for this task is Perl, because of its powerful
  6692.      text handling capabilities, and excellent resources available for
  6693.      making the jobs of CGI programmers easier. CGI programs can be written
  6694.      in any language, including Java.
  6695.      Unfortunately, the interface between the web server and the CGI program
  6696.      uses environment variables extensively. Use of environment variables
  6697.      has always been deprecated in Java, because of portability issues (not
  6698.      all systems have environment variables). The way to get around this is
  6699.      to write a "wrapper" for the Java program in a language that supports
  6700.      environment variables, and can then invoke the Java program with the
  6701.      appropriate environment data passed in as Java properties.
  6702.      Because the Java runtime environment is not a lightweight process, it
  6703.      might take a moment for the CGI program to get started before anything
  6704.      happens. This is particularly true on operating systems, like NT, that
  6705.      have a large overhead to spawning new processes.
  6706.      In preference to using Java for CGI on the server, you might consider
  6707.      using the Java servlet API in Netscape's Enterprise Server. This allows
  6708.      you to develop server-side programs in Java without suffering the same
  6709.      performance restrictions and other limitations of the CGI API.
  6710.      Other sites:
  6711.      See http://search.netscape.com/comprod/server_central/
  6712.      query/eval_guide/enterprise/advantage.html for more details.
  6713.  
  6714.  18. (Sect. 15) How can I write the "ping" program in Java?
  6715.  
  6716.      [*] You can't. Quoting from the Java Networking FAQ,
  6717.  
  6718.           Ping requires ICMP packets. These packets can only be created
  6719.           via a socket of the SOCK_RAW type. Currently, Java only
  6720.           allows SOCK_STREAM (TCP) and SOCK_DGRAM (UDP) sockets. It
  6721.           seems unlikely that this will be added very soon, since many
  6722.           Unix versions only allow SOCK_RAW sockets to be created by
  6723.           root, and winsock does not address ICMP packets (win32
  6724.           includes an unsupported and undocumented ICMP.DLL).
  6725.  
  6726.      Other sites:
  6727.           You can find the Java Networking FAQ at
  6728.           http://www.io.com/~maus/JavaNetworkingFAQ.html
  6729.  
  6730.                        -------------------------------
  6731.  
  6732. 16. Security
  6733.  
  6734.   1. (Sect. 16) What is a "trusted applet"?
  6735.  
  6736.      [*] JDK 1.1 introduced the notion of a "trusted applet" which is one
  6737.      that has been cryptographically signed to guarantee its origin and make
  6738.      it tamper-resistant. Trusted applets can be granted more system access
  6739.      privileges than untrusted applets.
  6740.      You preconfigure your browser with a list of whose X.509 certificate
  6741.      you trust, and then applets arrive with X.509's attesting to their
  6742.      keys. It's easier than it sounds.
  6743.  
  6744.   2. (Sect. 16) What is the story with Java and viruses? What is the
  6745.      blackwidow virus?
  6746.  
  6747.      [*] Java was designed with security in mind. The security features make
  6748.      it very difficult, probably impossible, to attach a virus (self-copying
  6749.      code) to a Java applet. There has never been a Java virus carried from
  6750.      system to system by applets.
  6751.      There has been mention of a "Java virus" called "BlackWidow" in the
  6752.      media (it was mentioned in Unigram in late 1996, and obliquely on the
  6753.      RISKS newsletter in February 1997). A request to the editor of Unigram
  6754.      for more information brought the answer that there was no more
  6755.      information, it was just a report of a rumor. As far as is known, this
  6756.      story exists only as rumors reported on by the press. There is no
  6757.      actual Java virus or blackwidow virus (there was a legitimate
  6758.      commercial product of that name, since renamed).
  6759.      In spring 1998 there were press reports of a "Java applet" called White
  6760.      Ghost. It turns out that it relies on security flaws in ActiveX, and
  6761.      the only susceptible systems are Microsoft's Active Desktop. If anyone
  6762.      has a URL for a copy of this code, and an analysis of it, please
  6763.      contact the FAQ author.
  6764.      In August 1998, Symantec had some information about a Java program
  6765.      (application) that could append itself to some other Java program. That
  6766.      is just normal file processing, no different to a program written in C,
  6767.      C++, Fortran, COBOL, etc. What makes PC viruses dangerous is when they
  6768.      have a hidden means of travelling between places, such as being
  6769.      attached to code that is automatically executed, like boot sector code,
  6770.      or Word macro initialization files.
  6771.      If anyone has more concrete information about a virus that can attack a
  6772.      Java applet (again, this is thought to be impossible), please contact
  6773.      the FAQ author.
  6774.  
  6775.   3. (Sect. 16) Why do I get the warning string "Unsigned Java Applet
  6776.      Window" at the bottom of popup windows in my applets?
  6777.  
  6778.      [*] This is a security feature, to make certain that users can always
  6779.      tell that a window asking for their password and credit card details
  6780.      (or whatever) is from an applet. There should be no way for an
  6781.      untrusted applet to work around this message.
  6782.      Also in the FAQ:
  6783.      See also the answer to Q12.7.
  6784.  
  6785.   4. (Sect. 16) Where can I find information on signing applets?
  6786.  
  6787.      [*] Please take a look at the "Code Signing for Java Applets" page at
  6788.      http://www.suitable.com/Doc_CodeSigning.shtml. The page explains how to
  6789.      sign your Java applet so that it can be used in both
  6790.      Navigator/Communicator and Internet Explorer.
  6791.  
  6792.   5. (Sect. 16) Where can I find crypto libraries for Java?
  6793.  
  6794.      [*] Cryptographic libraries are not part of the Java release because US
  6795.      Government policy classifies strong cryptography under the same rules
  6796.      as munitions. Its export is regulated under the International Traffic
  6797.      in Arms Regulations. Many people regard this as a Kafka-esque (and
  6798.      futile) attempt to stem the use of cryptography inside the US.
  6799.      Other sites:
  6800.         o A comprehensive and free crypto library (called Cryptix) is at:
  6801.           http://www.systemics.com/software
  6802.         o Another crypto library for Java is at:
  6803.           http://www.acme.com/java/software/Package-Acme.Crypto.html
  6804.           It includes Blowfish, CRC16, CRC32, DES, DES3, IDEA, RC4, ROT13
  6805.           (can they really call that "crypto"?), and more.
  6806.         o Another pure Java Cryptography toolkit is at
  6807.           http://www.freestylesoft.com/products/crypto/avalanche.html (free
  6808.           for personal use).
  6809.         o One commercial Java encryption source (from Ireland) is:
  6810.           http://www.baltimore.ie/jcrypto.htm
  6811.         o A complete crypto API for Java (with HTML documentation) at:
  6812.           http://www.geocities.com/SiliconValley/Heights/8298
  6813.           The library provides comprehensive and complete range of crypto
  6814.           library and functions covering DES, 3DES, IDEA, Blowfish ...and
  6815.           RSA, DH, DSA and PGP access to Java programmers. The crypto
  6816.           functions are based on the C cryptlib, by Peter Gutmann. It would
  6817.           be illegal to export this under current US government rules, but
  6818.           the author of the code is outside the US, and not subject to US
  6819.           export regulations. Download it today before it becomes illegal.
  6820.         o Also, data about Sun's Java Cryptography Extension (JCE) is
  6821.           available at:
  6822.           http://developer.java.sun.com/developer/earlyAccess/jdk12/jce.html
  6823.  
  6824.           (This may not be exported outside the USA and Canada).
  6825.         o An actual port of PGP v2.6.3i to Java is at:
  6826.           http://tassun.math.nsc.ru
  6827.  
  6828.   6. (Sect. 16) How do I find out what these terms mean?
  6829.  
  6830.      [*] Read Bruce Schneier's excellent book "Applied Cryptography 2nd Ed."
  6831.      for more info on what these terms mean. Read David Kahn's excellent (if
  6832.      exhaustive) book "The Codebreakers" for more info on the history and
  6833.      background of encryption.
  6834.  
  6835.   7. (Sect. 16) Where is Javasoft's Security FAQ?
  6836.  
  6837.      [*] Javasoft's security FAQ can be found at:
  6838.      http://java.sun.com/sfaq/index.html
  6839.      Other sites:
  6840.           http://java.sun.com/products/jdk/1.1/docs/guide/security/
  6841.  
  6842.                        -------------------------------
  6843.  
  6844. 17. For C and C++ Afficionados
  6845.  
  6846.   1. (Sect. 17) How do I translate C/C++ into Java or vice-versa?
  6847.  
  6848.      [*] In general it is not simple to translate C/C++ into Java, as Java
  6849.      lacks the arbitrary pointer arithmetic of those languages. If your C
  6850.      code does not use pointer arithmetic, automatic translation gets a lot
  6851.      simpler. Try these URLs:
  6852.           http://www.ist.co.uk (search for X-Designer 4.6: Java edition).
  6853.           http://members.aol.com/laffra/c2j.html
  6854.           http://www.ilog.com/
  6855.  
  6856.      Going the other way there are currently three freely-available tools to
  6857.      translate Java into C. It seems that these have been done for hacking
  6858.      value, rather than practical purposes.
  6859.         o j2c from Japan,
  6860.                http://www.webcity.co.jp/info/andoh/java/j2c.html
  6861.         o Toba from the Sumatra research project, translates 1.0.2 .class
  6862.           files into .c source code
  6863.                http://www.cs.arizona.edu/sumatra/toba
  6864.         o JCC from Nik Shaylor.
  6865.                http://www.geocities.com/CapeCanaveral/Hangar/4040/
  6866.  
  6867.      None of them support the AWT yet, and both j2c and JCC have additional
  6868.      restrictions.
  6869.  
  6870.      There's a product to convert Visual Basic to Java. Details at
  6871.           http://www.blackdirt.com and
  6872.           http://www.javadelphi.com (also a Delphi-to-Java source converter)
  6873.           and
  6874.           http://www.tvobjects.com
  6875.      There's a product to translate COBOL source to Java source, see
  6876.      http://www.Synkronix.com/
  6877.  
  6878.      This program dumps info about the class file:
  6879.           http://www.professionals.com/~cmcmanis/java/dump/index.html
  6880.  
  6881.      Chuck McManis was one of Sun's original Java implementors.
  6882.  
  6883.   2. (Sect. 17) How are finalizers different from C++ destructors?
  6884.  
  6885.      [*] Java objects are not explicitly deleted and do not have
  6886.      destructors. Instead they are implicitly garbage collected when the JVM
  6887.      realizes your program can no longer access them. Typically this
  6888.      technology is _not_ based on reference counting and _will_ cope with
  6889.      circular references.
  6890.  
  6891.      Every object has a routine called finalize() which will be called
  6892.      before the object is collected. This is Java's nearest equivalent to
  6893.      C++'s destructor. However, it is not a good idea to rely on
  6894.      finalization for the timely freeing of resources.
  6895.  
  6896.      This is because garbage collection and hence finalization may be
  6897.      arbitrarily delayed, and may never happen at all if the program
  6898.      terminates before it runs out of memory. You should instead provide
  6899.      your objects with methods similar to Graphics.dispose() to free
  6900.      resources, and call the dispose() method explicitly when you have
  6901.      finished using them - typically within the "finally" clause of a
  6902.      "try/catch" block. You may then call your dispose() method from within
  6903.      your finalize() method as a last-ditch attempt to free the resource if
  6904.      someone forgets.
  6905.  
  6906.      Alas, all this means the C++ idiom of "object construction is resource
  6907.      aquisition" does not translate well to Java. However, note that 90% of
  6908.      destructors in C++ are there to free memory, and the GC means you don't
  6909.      need to do that in Java. As well as fixing an important source of bugs,
  6910.      the GC is essential to Java's security model; without it you could
  6911.      forge object references by preserving the reference after the object
  6912.      has been deleted.
  6913.  
  6914.      If your program appears to be crashing due to running out of some
  6915.      system resource (like File, Window or Graphics handles), it probably
  6916.      because the system is running out of handles before it has run out of
  6917.      memory. Check that you have called the dispose() method (or equivalent)
  6918.      on every object that uses system resources. You can help the GC a
  6919.      little bit more by explicitly NULLing out references that you've
  6920.      finished with.
  6921.  
  6922.   3. (Sect. 17) What's the Java equivalent of sizeof()?
  6923.  
  6924.      [*] There isn't one. sizeof() in C and C++ is used in three main
  6925.      places:
  6926.        1. To check on the size of a primitive type. In Java, the sizes of
  6927.           primitive types are fixed in the language specification (a short
  6928.           is _always_ 16 bits; an int is _always_ 32 bits, etc), so this is
  6929.           no longer necessary.
  6930.        2. In memory allocation (i.e. malloc (32 * (sizeof(int));) In Java
  6931.           you always allocate a specific type of object, rather than a block
  6932.           of raw memory that you will fill as you like. The system always
  6933.           knows the size of the kind of objects you are allocating. So
  6934.           sizeof is not needed.
  6935.        3. In pointer arithmetic (i.e. p += sizeof (int)) Pointer arithmetic
  6936.           of this type is not allowed in Java, so this isn't necessary,
  6937.           either.
  6938.  
  6939.      For all these reasons, there is no need for a Java sizeof() operator.
  6940.      Some people have suggested that you can find out the size of an object
  6941.      by having the object serialize itself to a ByteArrayOutputStream, and
  6942.      looking at the bytearray.length.
  6943.  
  6944.      That won't work because a lot of additional data is written when an
  6945.      object is serialized. The additional data includes a description of the
  6946.      class, any objects referenced by the serialized object, null references
  6947.      (written as a single byte), etc. If you write another instance of the
  6948.      same class, the amount of data written can differ dramatically. And if
  6949.      you serialize the same object again, it isn't written at all -- even if
  6950.      its data fields have changed! Instead, a one byte token and a four byte
  6951.      "sequence number" that refer to the first writing are output. Using
  6952.      Object Serialization to determine the size of an object does not
  6953.      (except by coincidence) give the right answer.
  6954.  
  6955.   4. (Sect. 17) Does Java have the equivalent of "const" arguments in C and
  6956.      C++?
  6957.  
  6958.      [*] Java 1.1 adds the ability to use the "final" keyword to make
  6959.      arguments constant. When used to qualify a reference type, however,
  6960.      this keyword indicates that the reference is constant, not that the
  6961.      object or array referred to is constant. For example, the following
  6962.      Java code:
  6963.  
  6964.           void foo(final MyClass c, final int a[]) {
  6965.               c.field = 7; // allowed
  6966.               a[0] = 7; // allowed
  6967.               c = new MyClass(); // final means this is NOT allowed
  6968.               a = new int[13]; // final means this is NOT allowed
  6969.           }
  6970.  
  6971.      is roughly equivalent to the following C/C++ code:
  6972.  
  6973.           void foo(MyClass * const c, int * const a) {
  6974.               c->field = 7; // allowed
  6975.               a[0] = 7; // allowed
  6976.               c = new MyClass(); // const means this is NOT allowed
  6977.               a = new int[13]; // const means this is NOT allowed
  6978.           }
  6979.  
  6980.      Java does not have any equivalent to the following C/C++ function
  6981.      declarations:
  6982.  
  6983.           void foo(const MyClass *c); // a pointer to a const class
  6984.           void foo(const int *a); // a pointer to a const int
  6985.           void foo(const int a[]); // a pointer to an array of const ints
  6986.  
  6987.   5. (Sect. 17) Are there any hacks around this?
  6988.  
  6989.      [*] Certainly! There are always hacks around stuff. One way of
  6990.      enforcing constant values is to have two interfaces, a constant one and
  6991.      a non-constant one, e.g.
  6992.  
  6993.           public interface ConstFoo {
  6994.              int getValue();
  6995.           }
  6996.  
  6997.           public interface Foo extends ConstFoo {
  6998.               int getValue();
  6999.               void setValue(int i);
  7000.           }
  7001.  
  7002.      Then when you want to receive a parameter that cannot be modified you
  7003.      have:
  7004.  
  7005.           void noChange(ConstFoo foo);
  7006.  
  7007.  
  7008.      For a parameter that can be modified
  7009.  
  7010.           void change(Foo foo);
  7011.  
  7012.  
  7013.   6. (Sect. 17) How can I write C/C++ style assertions in Java?
  7014.  
  7015.      [*] The two classes shown below provide an assertion facility in Java.
  7016.      Set Assert.enabled to true to enable the assertions, and to false to
  7017.      disable assertions in production code. The AssertionException is not
  7018.      meant to be caught--instead, let it print a trace. Since the exception
  7019.      is not meant to be caught, we just extend Error instead of
  7020.      RuntimeException. As with RuntimeException, a method does not need to
  7021.      declare that it throws Error. In addition programmers are less likely
  7022.      to write "catch(Error) ..." than "catch(RuntimeException)".
  7023.  
  7024.      With a good optimizing compiler there will be no run time overhead for
  7025.      many uses of these assertions when Assert.enabled is set to false.
  7026.      However, if the condition in the assertion may have side effects, the
  7027.      condition code cannot be optimized away. For example, in the assertion
  7028.  
  7029.           Assert.assert(size() <= maxSize, "Maximum size exceeded");
  7030.  
  7031.      the call to size() cannot be optimized away unless the compiler can see
  7032.      that the call has no side effects. C and C++ use the preprocessor to
  7033.      guarantee that assertions will never cause overhead in production code.
  7034.      Without a preprocessor, it seems the best we can do in Java is to write
  7035.  
  7036.           Assert.assert(Assert.enabled && size() <= maxSize, "Too big");
  7037.  
  7038.           Alternatively, use
  7039.  
  7040.               if (Assert.enabled)
  7041.                   Assert.assert( size() <= maxSize, "Too big" );
  7042.  
  7043.      In this case, when Assert.enabled is false, the method call can always
  7044.      be optimized away totally, even if it has side effects. However, an
  7045.      opposing view holds that even this might not work in the face of java's
  7046.      late binding. If the Assert class is in a package, and if the computer
  7047.      the applet/application is running on has a different version with
  7048.      Assert.enabled being true, then it's possible that assertions *should*
  7049.      be enabled in that case. Therefore, the compiler can't assume that
  7050.      enabled is *false* at runtime just because it *is* false in the
  7051.      compilation environment. This may be thought perverse, but it could
  7052.      happen.
  7053.      If a language lawyer wants to weigh in on this theory, please go ahead.
  7054.  
  7055.           public class AssertionException extends Error {
  7056.               public AssertionException(String s) {
  7057.                  super(s);
  7058.               }
  7059.           }
  7060.  
  7061.           public final class Assert {
  7062.               public static final boolean enabled = true;
  7063.               public static final void assert(boolean b, String s) {
  7064.                   if (enabled && !b)
  7065.                       throw new AssertionException(s);
  7066.               }
  7067.           }
  7068.  
  7069.   7. (Sect. 17) How do I do stuff like scanf and sscanf in C/C++? And how do
  7070.      I do stuff like sprintf, e.g.
  7071.  
  7072.      float x = 12345.6789;
  7073.      printf("%6.3f/n", x);
  7074.  
  7075.      [*] You can break a string like "5 loaves 2 fishes" into its parts by
  7076.      using java.util.StringTokenizer. This is the Java equivalent of
  7077.      sscanf().
  7078.  
  7079.      StreamTokenizer does a similar thing on a file or any stream (i.e, what
  7080.      scanf() and fscanf() do in C).
  7081.  
  7082.      To do formatted character output, create a format string, and then use
  7083.      that to format your binary value, e.g.
  7084.  
  7085.           import java.text.*;
  7086.  
  7087.           float fi = 1234.56789F;
  7088.           DecimalFormat mydf = new DecimalFormat( "###0.000" );
  7089.           mydf.setMinimumIntegerDigits(3);  // for example
  7090.           System.out.println( mydf.format(fi) );
  7091.  
  7092.      gives:
  7093.           1234.567
  7094.  
  7095.      If you want to see a float print out as "0.0000001" instead of "1E-7",
  7096.      use:
  7097.  
  7098.      java.text.DecimalFormat myFmt = new
  7099.          java.text.DecimalFormat("#,###,###,###.############");
  7100.      System.out.println(myFmt.format(myFloat));
  7101.  
  7102.      There are lots of different characters you can feed to the
  7103.      DecimalFormat constructor, not just "0" and "#". See
  7104.      $JAVAHOME/src/java/text/DecimalFormat.java source for details.
  7105.  
  7106.   8. (Sect. 17) What is the Java equivalent of C++'s "friend"?
  7107.  
  7108.      [*] The keyword "friend" in C++ is a hack to allow a piece of code to
  7109.      access the private member declarations of another class. In Java, you
  7110.      would do this by labelling, not the friend, but the private members.
  7111.      Instead of making them private, make them either protected or package
  7112.      (no keyword) or public.
  7113.  
  7114.      The four different Java protection levels are: private, package,
  7115.      protected, and public.
  7116.         o private members can only be accessed by the containing class and
  7117.           internal classes.
  7118.         o package (specified by omitting other keywords) is the default
  7119.           level of protection; members are accessible from any class within
  7120.           the package of the containing class.
  7121.         o protected is package-level-access plus access to sub-classes of
  7122.           the containing class. So "protected" is less protected than the
  7123.           default.
  7124.         o public fields in public classes are accessible from all classes.
  7125.  
  7126.   9. (Sect. 17) Does anything like the C++ Standard Template Library exist
  7127.      for Java?
  7128.  
  7129.      [*] Yes, only it's better and simpler to use in Java. It's called the
  7130.      Java Generic Library. This library (JGL) is freely downloadable from
  7131.      http://www.objectspace.com/
  7132.  
  7133.      It includes about a dozen nice data structures (including sets and
  7134.      bags) and algorithms like unions, searching, and sorting.
  7135.  
  7136.      It has over 100,000 users and 11 OEM distributors. [Some Java vendors
  7137.      are bundling it with their next release]
  7138.  
  7139.  10. (Sect. 17) What happens to post-increment when an exception is thrown?
  7140.  
  7141.      [*] If you have the code:
  7142.  
  7143.          array[i++] = foo();
  7144.  
  7145.      and foo() throws an exception, i will be incremented anyway. This can
  7146.      cause problems if sometimes foo() throws an exception and you don't
  7147.      want i incremented in cases when it does.
  7148.  
  7149.      This is a consequence of JLS 15.25.1 and 15.6.1 "the left-hand operand
  7150.      of a binary operator appears to be fully evaluated before any part of
  7151.      the right-hand operand is evaluated." (assignment is taken as a binary
  7152.      operator). Note that this is not how C++ behaves.
  7153.  
  7154.                        -------------------------------
  7155.  
  7156. 18. Java Idioms
  7157.  
  7158.      See also the list of Java Design Patterns at
  7159.      http://http://c2.com/cgi/wiki?JavaIdioms
  7160.  
  7161.   1. (Sect. 18) What are the naming conventions in Java?
  7162.  
  7163.      [*] The naming conventions are straightforward:
  7164.         o Package names are guaranteed uniqueness by using the Internet
  7165.           domain name in reverse order: com.javasoft.jag - the "com" or
  7166.           "edu" (etc.) part used to be in upper case, but now lower case is
  7167.           the recommendation.
  7168.         o Class and interface names are descriptive nouns, with the first
  7169.           letter of each word capitalized: PolarCoords. Interfaces are often
  7170.           called "something-able", e.g. "Observable", "Runnable",
  7171.           "Sortable".
  7172.         o Object and data (field) names are nouns/noun phrases, with the
  7173.           first letter lowercase, and the first letter of subsequent words
  7174.           capitalized: currentLimit.
  7175.         o Method names are verbs/verb phrases, with the first letter
  7176.           lowercase, and the first letter of subsequent words capitalized:
  7177.           calculateCurrentLimit.
  7178.         o Constant (final) names are in caps: UPPER_LIMIT.
  7179.      Other sites:
  7180.         o Check out the section "Naming Conventions" in the language
  7181.           specification:
  7182.           http://java.sun.com/docs/books/jls/html/6.doc.html#11186
  7183.         o Also take a look at Doug Lea's draft coding standard:
  7184.           http://gee.cs.oswego.edu/dl/html/javaCodingStd.html
  7185.  
  7186.   2. (Sect. 18) How do I convert a String to an int?
  7187.  
  7188.      [*] There are several ways. The most straightforward is:
  7189.  
  7190.          String mystring = numString.trim();
  7191.          int i = Integer.parseInt(myString);
  7192.          long l = Long.parseLong(myString)
  7193.  
  7194.  
  7195.      or
  7196.  
  7197.          String mystring = numString.trim();
  7198.          i = Integer.parseInt(myString,myIntRadix);
  7199.  
  7200.  
  7201.      Note 1: There is a gotcha with parseInt - it will throw a
  7202.      NumberFormatException for String values in the range "80000000" to
  7203.      "ffffffff". You might expect it to interpret them as negative, but it
  7204.      does not. The values have to be "-80000000" .. "-ffffffff" to be
  7205.      properly recognized as negative values. This is true for all radixes.
  7206.      According to Bug Parade bug report 4068580, the proper way to generate
  7207.      negative-valued hex Strings for eventual use by parseInt() is with
  7208.      Integer.toString(i, 16). Once that high "sign bit" is on, without the
  7209.      accompanying character, parseInt() says "too big".
  7210.      Note 2: There are similar methods for Byte, Short, and Long. Use
  7211.      myString.trim() to get rid of unwanted spaces before the conversion.
  7212.      Some of the parse methods can cope with spaces, others can't. They were
  7213.      written by two different people.
  7214.  
  7215.          int i = Integer.valueOf(my_str).intValue();
  7216.  
  7217.  
  7218.      also works but involves the creation of an extra object. Note: the
  7219.      pre-FCS JDK 1.2 documentation at one point said that parseDouble and
  7220.      parseFloat methods were to be introduced, but this does not seem to be
  7221.      the case (see bug 4160672). JDK 1.2.
  7222.  
  7223.          float f = Float.valueOf(my_str).floatValue();
  7224.          double d = Double.valueOf(my_str).doubleValue();
  7225.  
  7226.  
  7227.   3. (Sect. 18) How do I convert an int to a string?
  7228.  
  7229.      [*] Try any of these:
  7230.  
  7231.          String s = String.valueOf(i);
  7232.  
  7233.  
  7234.      or
  7235.  
  7236.          String s = Integer.toString(i);
  7237.  
  7238.  
  7239.      or
  7240.  
  7241.          String s = Integer.toString(i, radix);
  7242.  
  7243.  
  7244.      or
  7245.  
  7246.          // briefer but may result in extra object allocation.
  7247.          String s = "" + i;
  7248.  
  7249.  
  7250.      Note: There are similar classes for Double, Float, Long, etc.
  7251.  
  7252.   4. (Sect. 18) How do I print the hex value of an int?
  7253.  
  7254.      [*] You can print the hex equivalent of an int with:
  7255.  
  7256.          int i = 0xf1;
  7257.          System.out.println("i is hex " + Integer.toHexString(i) );
  7258.  
  7259.  
  7260.      OK, how do I read a hex string into an int?
  7261.  
  7262.          int i = Integer.valueOf(myHexString, 16).intValue();
  7263.  
  7264.  
  7265.   5. (Sect. 18) How can you send a function pointer as an argument?
  7266.  
  7267.      [*] Simple answer: use a "callback". Make the parameter an interface
  7268.      and pass an argument instance that implements that interface.
  7269.  
  7270.          public interface CallShow { public void Show( ); }
  7271.  
  7272.          public class ShowOff implements CallShow {
  7273.              public void Show( ) { .... }
  7274.  
  7275.          public class ShowOff2 implements CallShow {
  7276.              public void Show( ) { .... }
  7277.  
  7278.          public class UseShow {
  7279.              CallShow savecallthis;
  7280.  
  7281.              UseShow( CallShow withthis ) {
  7282.                  savecallthis = withthis;
  7283.              }
  7284.  
  7285.              void ReadyToShow( ) { savecallthis.Show( ); }
  7286.          }
  7287.  
  7288.          // in some other class that uses all this stuff:
  7289.          UseShow use_1 = new UseShow( new ShowOff() );
  7290.          UseShow use_2 = new UseShow( new Showoff2() );
  7291.  
  7292.  
  7293.      and then the ReadyToShow() method on use_1 or use_2 will call the
  7294.      appropriate method, as if you had stored a pointer to the method.
  7295.  
  7296.   6. (Sect. 18) How do I execute a command from Java?
  7297.  
  7298.      [*] Use
  7299.  
  7300.          Runtime.getRuntime().exec( myCommandString )
  7301.  
  7302.  
  7303.      where myCommandString is something like "/full/pathname/command". An
  7304.      applet will need to be signed in order to allow this.
  7305.  
  7306.      Note, there are known bugs associated with reading output from
  7307.      commands.
  7308.  
  7309.   7. (Sect. 18) How do I do I/O redirection in Java using exec()?
  7310.  
  7311.      [*] This solution works on Unix platforms using either JDK 1.0.2, or
  7312.      JDK 1.1. The trick is to use an array of Strings for the command line:
  7313.  
  7314.          String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
  7315.  
  7316.  
  7317.      If you don't do this, and simply use a single string, the shell will
  7318.      see the -c and /bin/ls and ignore everything else after that. It only
  7319.      expects a single argument after the -c.
  7320.  
  7321.          import java.io.*;
  7322.          import java.util.*;
  7323.  
  7324.          class IoRedirect {
  7325.          public static void main(String Argv[]) {
  7326.              try {
  7327.                  String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
  7328.                  Process p = Runtime.getRuntime().exec(command);
  7329.                  p.waitFor();
  7330.                  System.out.println("return code: "+ p.exitValue());
  7331.              } catch (IOException e) {
  7332.                  System.err.println("IO error: " + e);
  7333.              } catch (InterruptedException e1) {
  7334.                  System.err.println("Exception: " + e1.getMessage());
  7335.              }
  7336.          }
  7337.          }
  7338.  
  7339.  
  7340.   8. (Sect. 18) So why can't I exec common DOS commands this way (as in
  7341.      17.7)?
  7342.  
  7343.      [*] The reason is that many of the DOS commands are not individual
  7344.      programs, but merely "functions" of command.com. There is no DIR.EXE or
  7345.      COPY.EXE for example. Instead, one executes the command processor
  7346.      (shell) explicitly with a request to perform the built-in command, like
  7347.      so:
  7348.      Runtime.getRuntime().exec("command.com /c dir") for example. On NT, the
  7349.      command interpreter is "cmd.exe", so the statement would be
  7350.      Runtime.getRuntime().exec("cmd /c dir")
  7351.      This occurs on any OS where some commands are actually interpreted
  7352.      directly by the shell.
  7353.  
  7354.   9. (Sect. 18) OK, how do I read the output of a command?
  7355.  
  7356.      [*] As above (17.6, 17.7), adjusted like this:
  7357.  
  7358.          BufferedReader pOut= new BufferedReader(
  7359.          new InputStreamReader(p.getInputStream()));
  7360.          try {
  7361.          String s = pOut.readLine();
  7362.          while (s != null) {
  7363.              System.out.println(s);
  7364.              s = pOut.readLine();
  7365.          }
  7366.          } catch (IOException e) { }
  7367.  
  7368.  
  7369.      Another possibility is to read chunks of whatever length as they come
  7370.      in:
  7371.  
  7372.          ...
  7373.  
  7374.          p = r.exec(cmd);
  7375.          InputStream is = p.getInputStream();
  7376.          int len;
  7377.          byte buf[] = new byte[1000];
  7378.          try {
  7379.              while( (len = is.read(buf)) != -1 ) {
  7380.                  String str = new String(buf,0,0,len);
  7381.                  System.out.println( "Process out: " + str );
  7382.              }
  7383.          } catch( java.io.EOFException eof ) { ...
  7384.          } catch( java.io.IOException ioe ) { ...  }
  7385.  
  7386.  
  7387.  10. (Sect. 18) How do I compile code which has a cyclic dependency, i.e
  7388.      class pkg1.X contains a reference to class pkg2.Y ?
  7389.  
  7390.      [*] You throw both classes at the compiler at the same time.
  7391.      javac pkg1/X.java pkg2/Y.java
  7392.  
  7393.  11. (Sect. 18) How can I store the errors from the javac compiler in a DOS
  7394.      file? javac foo.java > errorfile doesn't work.
  7395.  
  7396.      [*] javac writes errors to stderr, so on NT use:
  7397.      javac myfile.java 2> errors.dat
  7398.      On Win95, this doesn't work (as command.com is very poor software), so
  7399.      you have to use the javac error redirection mechanism:
  7400.      javac -J-Djavac.pipe.output=true myfile.java > errors.txt You typically
  7401.      use this when a compilation produces a lot of error messages, and they
  7402.      scroll off the DOS window before you can read them. Alternatively, you
  7403.      can get a scollbar to appear on a DOS window by changing the properties
  7404.      with the "Layout" tab. Change the Screen Buffer Size Height: to some
  7405.      multiple > 1 of the Window Size Height. E.g. use a buffer height of 100
  7406.      and screen height of 25 (the default). This will give you three buffers
  7407.      of scroll "history."
  7408.  
  7409.  12. (Sect. 18) How can I pretty-print Java source?
  7410.  
  7411.      [*] Try:
  7412.         o http://www.CS.ORST.EDU/~speton/percolator/ (currently in beta)
  7413.         o http://www.geocities.com/~starkville
  7414.         o http://www.parallax.co.uk/~rolf/download/jpp.pl
  7415.      Some Unix utilities work adequately:
  7416.         o indent (fails with "//" comments though)
  7417.         o cb (very few style choices though)
  7418.         o alias printjava 'vgrind -lC++ -t -w \!* | lp' works pretty well
  7419.           too.
  7420.      Perhaps the best tools are the GNU utilities. Use enscript to generate
  7421.      postscript files with Java-specific formatting. Then use
  7422.      GhostScript/GhostView to preview and print the files to a
  7423.      non-PostScript printer, if necessary. The scripts can be found at:
  7424.         o GNU Enscript - pretty printer and PostScript formatter
  7425.         o Ghostscript, Ghostview, and GSView for Unix
  7426.         o gsv25w32.zip - GSView for NT (requires the following Ghostscript
  7427.           files)
  7428.         o gs510ini.zip - Ghostscript configuration, initialization, and
  7429.           example files
  7430.         o gs510w32.zip - Ghostscript core binaries for Windows NT
  7431.         o gs510fn1.zip - Ghostscript standard fonts
  7432.  
  7433.  13. (Sect. 18) What is the point of creating the temporary reference to
  7434.      this.layoutMgr?
  7435.  
  7436.      [*] This code is from the 1.0 AWT, and the programmer was probably
  7437.      pretty skilled.
  7438.  
  7439.          public synchronized void layout() {
  7440.               LayoutManager layoutMgr = this.layoutMgr;
  7441.               if (layoutMgr != null) {
  7442.                   layoutMgr.layoutContainer(this);
  7443.               }
  7444.          }
  7445.  
  7446.  
  7447.      The code makes a local copy of a global variable for one or both of two
  7448.      reasons.
  7449.      The first reason is that accessing local variables can be faster than
  7450.      accessing (non final) member variables It's good for loops or where
  7451.      there are many references in the source.
  7452.      The second reason is so that even if other threads update the global,
  7453.  
  7454.          this.layoutMgr = someOtherLayoutMgr;
  7455.  
  7456.      This method will still have a pointer to the original layoutMgr.
  7457.      If the local variable were omitted, and another thread used the
  7458.      setLayout() method to change layoutMgr to null between when the layout
  7459.      method checked for null and when it invoked layoutMgr's layoutContainer
  7460.      method, a NullPointerException would result.
  7461.      Note that the synchronized keyword on the layout method doesn't help
  7462.      any, since setLayout (which could make such a dire change) isn't
  7463.      synchronized. Synchronized methods only lock out other synchronized
  7464.      methods on this object. (The unhelpful synchronized keyword on the
  7465.      layout method is gone in JDK 1.1.)
  7466.      There are two alternative solutions. One would be to make setLayout
  7467.      synchronized and make layoutMgr private, so that it can't be set other
  7468.      ways. This provides a stronger form of thread serialization, in that
  7469.      you would never be able to see an old layout manager being used after
  7470.      it had been replaced. However, it is slower. Another option that
  7471.      provides no increase in thread serialization over the original would be
  7472.      to catch the NullPointerException.
  7473.      Threaded programming is hard! This idiom was probably put in place by
  7474.      someone who got really bitten by this in the past.
  7475.  
  7476.  14. (Sect. 18) What is the difference between "a & b" and "a && b" ?
  7477.  
  7478.      [*] "a & b" takes two boolean operands, or two integer operands. It
  7479.      always evaluates both operands. For booleans, it ANDs both operands
  7480.      together producing a boolean result. For integer types, it bitwise ANDs
  7481.      both operands together, producing a result that is the promoted type of
  7482.      the operands (i.e. long, or int). "|" is the corresponding bitwise OR
  7483.      operation. "^" is the corresponding bitwise XOR operation.
  7484.  
  7485.      "a && b" is a "conditional AND" which only takes boolean operands. It
  7486.      always avoids evaluating its second operand if possible. If a is
  7487.      evaluated to false, the AND result must be "false" and the b operand is
  7488.      not evaluated. This is sometimes called "short-circuited" evaluation.
  7489.      "||" is the corresponding short-circuited OR operation.
  7490.  
  7491.      Possible mnemonic: The longer operators "&&" or "||" try to shorten
  7492.      themselves by not evaluating the second operator if they can.
  7493.  
  7494.  15. (Sect. 18) If I create a thread, and then null out the reference to it,
  7495.      what happens to the thread? Does it get interrupted or what?
  7496.  
  7497.      [*] The code looks like this:
  7498.  
  7499.          Thread t = new Thread( my_runnable_obj );
  7500.          t.start();
  7501.          ...
  7502.          t = null; // what happens to the thread?
  7503.  
  7504.  
  7505.      The answer is that you may no longer have a reference to the thread,
  7506.      but the JVM still does. Once a thread is started, and as long as it
  7507.      keeps running, it is a root object. Root objects are the starting
  7508.      points for "things in use" that the garbage collector uses.
  7509.  
  7510.  16. (Sect. 18) How do I calculate the number of days between two dates?
  7511.  
  7512.      [*] There is no API for this (there should be), but you can calculate
  7513.      it by hand like this:
  7514.  
  7515.          Calendar earlierDate = new GregorianCalendar();
  7516.          Calendar laterDate = new GregorianCalendar();
  7517.  
  7518.          earlierDate.set(1997, 1, 1, 0, 0, 0);    // Jan 01, 1997
  7519.          laterDate.set(1998, 1, 1, 0, 0, 0);      // Jan 01, 1998
  7520.  
  7521.          // the first getTime() returns a Date, the second takes
  7522.          // that Date object and returns millesecs since 1/1/70.
  7523.          // The API has misleading and horrible naming here, sorry.
  7524.          long duration = laterDate.getTime().getTime() -
  7525.                                    earlierDate.getTime().getTime();
  7526.  
  7527.          long nDays = duration / (24 * 60 * 60 * 1000);
  7528.          System.out.println("difference in days: " + nDays);
  7529.  
  7530.  
  7531.      Or, use int julian = myCalendar.get(Calendar.DAY_OF_YEAR); and
  7532.      subtract, making sure to subtract the years too. Alternatively, use
  7533.      BigDate at http://mindprod.com.
  7534.  
  7535.      For the ultimate in generality, get ACM's Collected Algorithm 199,
  7536.      recode it in Java (takes about 30 minutes), compute the Julian date for
  7537.      each end point, and subtract the two numbers. If you do this, please
  7538.      donate the code to public domain, and send it to me. The ACM algorithms
  7539.      aren't online (they should be). Look for this one in Communications of
  7540.      the ACM, page 444, vol 6, issue 8, Aug 1963. There's a follow up in
  7541.      CACM, p661, vol 7, issue 11, Nov 1964 by D.K. Oppenheim. The algorithm
  7542.      is in Algol 60 for all you amateur historians.
  7543.  
  7544.  17. (Sect. 18) How can a Java program determine the level of JDK support
  7545.      given by the underlying VM? I.e. is it running in a JDK 1.0.2 or 1.1
  7546.      VM?
  7547.  
  7548.      [*] Look at the java.version system property with:
  7549.  
  7550.          String ver = System.getProperty("java.version");
  7551.  
  7552.  
  7553.      There isn't a lot of standardization on the string contents however.
  7554.      Another possibility is to try { ... } to load a class that is unique to
  7555.      one release, like this:
  7556.  
  7557.      boolean isJDK1_1 = true;
  7558.      try {
  7559.          // java.awt.Cursor is available only in the 1.1.x JDK
  7560.          Class cls = Class.forName("java.awt.Cursor");
  7561.      } catch (Exception e)    {
  7562.          // we should have written 'ClassNotFoundException e',
  7563.          // but Communicator generates security exception instead.
  7564.          isJDK1_1 = false;
  7565.      }
  7566.  
  7567.      This approach has the advantage that it can be compiled by any version
  7568.      compiler.
  7569.  
  7570.  18. (Sect. 18) How can I set a system property?
  7571.  
  7572.      [*] JDK 1.2 has
  7573.  
  7574.          System.setProperty( "property", "new value" );
  7575.  
  7576.  
  7577.      Until then, you can get all the properties, and set just the one you
  7578.      want with code like this:
  7579.  
  7580.          System.getProperties().put("property", "new value" );
  7581.  
  7582.  
  7583.  19. (Sect. 18) How can I clone using serialization?
  7584.  
  7585.      [*] Look at the code below, submitted by expert programmer John Dumas.
  7586.      It uses serialization to write an object into a byte array, and reads
  7587.      it back to reconstitute a fresh copy. This is a clever hack!
  7588.  
  7589.      import java.io.ByteArrayOutputStream;
  7590.      import java.io.ByteArrayInputStream;
  7591.      import java.io.ObjectOutputStream;
  7592.      import java.io.ObjectInputStream;
  7593.  
  7594.      public class Cloner {
  7595.         private Cloner() {}
  7596.  
  7597.         public static Object cloneObject(Object o) throws Exception {
  7598.            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
  7599.            ObjectOutputStream out     = new ObjectOutputStream(bOut);
  7600.  
  7601.            out.writeObject(o);
  7602.  
  7603.            ByteArrayInputStream bIn =
  7604.                     new ByteArrayInputStream(bOut.toByteArray());
  7605.            ObjectInputStream in     = new ObjectInputStream(bIn);
  7606.  
  7607.            return(in.readObject());
  7608.         }
  7609.  
  7610.         public static void main(String args[]) throws Exception {
  7611.            java.util.Vector v = new java.util.Vector();
  7612.            v.addElement(new StringBuffer("Hello"));
  7613.  
  7614.            java.util.Vector vClone =
  7615.                       (java.util.Vector)Cloner.cloneObject(v);
  7616.  
  7617.            // Changing the StringBuffer int the cloned vector has no
  7618.            // effect on the original StringBuffer object --
  7619.            // demonstrating that we have indeed done a deep copy
  7620.  
  7621.            ((StringBuffer)vClone.elementAt(0)).append(" world");
  7622.  
  7623.            StringBuffer sb = (StringBuffer)v.elementAt(0);
  7624.            System.out.println(sb.toString());
  7625.  
  7626.            sb = (StringBuffer)vClone.elementAt(0);
  7627.            System.out.println(sb.toString());
  7628.  
  7629.            int array[] = { 1, 2, 3, 4, 5 };
  7630.  
  7631.            int arrayClone[] = (int [])Cloner.cloneObject(array);
  7632.  
  7633.            // Again, changes to an element in the cloned array do not
  7634.            // have any effect on the original
  7635.  
  7636.            arrayClone[0]++;
  7637.  
  7638.            System.out.println(array[0]);
  7639.            System.out.println(arrayClone[0]);
  7640.         }
  7641.      }
  7642.  
  7643.      The main() routine is just a driver. All the cleverness is in the very
  7644.      brief cloneObject(). It does a "deep" clone, which is what you usually
  7645.      want (though Java gives you a "shallow" clone by default).
  7646.  
  7647.                        -------------------------------
  7648.  
  7649. 19. Java GOTCHA'S
  7650.  
  7651.   1. (Sect. 19) What is a "GOTCHA" (for non-English native speakers)?
  7652.  
  7653.      [*] It is an abbreviation of "Got you!" It is the triumphant
  7654.      exclamation that a bug or programming idiom makes as it traps the
  7655.      unwary programmer. This section details some of the popular "gotcha's"
  7656.      of Java.
  7657.  
  7658.      See also the list of Java Gotcha's at
  7659.      http://mindprod.com/gloss.html
  7660.  
  7661.   2. (Sect. 19) Why can't I filter filenames with the accept() method?
  7662.  
  7663.      [*] It's a known bug. FileDialog doesn't call FilenameFilter.accept().
  7664.      The bug id is 4031440, and it can be seen at the Java Developer
  7665.      Connection.
  7666.  
  7667.      There is no way to implement FilenameFilter support with the current
  7668.      reliance on the Win32 common file dialog. To support FilenameFilter,
  7669.      the FileDialog needs to issue a callback for each file it wants to
  7670.      display, which the FilenameFilter can veto. But the Win32 common
  7671.      FileDialog doesn't have any way to issue callbacks. Instead it accepts
  7672.      simple wildcard patterns for choosing files which match a certain
  7673.      pattern. That's a reasonable alternative to FilenameFilters, but that
  7674.      model isn't supported by the current Java API.
  7675.  
  7676.      FileDialog will need to be rewritten to support FilenameFiltering, and
  7677.      JDK 1.2 is the earliest feasible point for changing the API.
  7678.  
  7679.      JFC has a JFileChooser class that is probably a better bet for you to
  7680.      use for file dialogs.
  7681.  
  7682.   3. (Sect. 19) I changed a final value, and recompiled just the file that
  7683.      it was in, and the entire rest of the program used the old value!
  7684.  
  7685.      [*] This is the "expected" behavior. If you have this in one file
  7686.  
  7687.      class Flags { final static boolean debug = true; }
  7688.  
  7689.      and you change it to, and recompile just this file:
  7690.  
  7691.      class Flags { final static boolean debug = false; }
  7692.  
  7693.      Then the rest of your Java .class files will still see it as "true".
  7694.  
  7695.      When you declare a "static final int" (or any other primitive), the
  7696.      compiler turns that into a compile time constant whose value can be
  7697.      substituted wherever it is used in your program. If you update the
  7698.      value in the source file, you'll need to recompile every class that
  7699.      uses it.
  7700.  
  7701.      See Java Language Specification, section 13.4.8 "final Fields and
  7702.      Constants": "We call a field that is static, final, and initialized
  7703.      with a compile-time constant expression a primitive constant. If a
  7704.      field is a primitive constant, then deleting the keyword final or
  7705.      changing its value will not break compatibility with pre-existing
  7706.      binaries by causing them not to run, but they will not see any new
  7707.      value for the constant unless they are recompiled."
  7708.  
  7709.   4. (Sect. 19) What is the "substring trap"?
  7710.  
  7711.      [*] The "substring trap" is the name for a mistake that is all too easy
  7712.      to make when using the substring() method of class String. The method
  7713.      signature is:
  7714.  
  7715.      public String substring(int beginIndex, int endIndex)
  7716.  
  7717.      The name "endIndex" suggests that is the index where the Substring
  7718.      ends.
  7719.  
  7720.      But in fact, the substring extends only to the character at position
  7721.      (endIndex-1)! It seems to be done this way so that
  7722.      s.substring(0,s.length()) is equal to s. If so, the name of the second
  7723.      parameter should be something like endInxLessOne or Length. But not the
  7724.      confusing and misleading endIndex. Beware of the substring trap.
  7725.  
  7726.   5. (Sect. 19) Why does getGraphics() return null on my offscreen image?
  7727.  
  7728.      [*] The following code
  7729.  
  7730.      class MyFrame extends Frame {
  7731.        MyFrame() {
  7732.          Image offscreen = createImage(100,100);
  7733.          Graphics offg = offscreen.getGraphics();
  7734.          }
  7735.        ...
  7736.        }
  7737.  
  7738.      will usually not work, since the peer will not exist at this time.
  7739.      Without the peer for the Frame, you cannot succeed in creating
  7740.      offscreen Images. (There's no problem creating Produced Images without
  7741.      a peer. Trying to draw them, of course, is another matter).
  7742.  
  7743.      One "standard" form of offscreen code looks like this: (note the reuse
  7744.      of the Graphics and Image objects for as long as possible)
  7745.  
  7746.      class Gumble extends java.awt.Something {
  7747.        private Image offi;
  7748.        private Graphics offg;
  7749.  
  7750.        public void update(Graphics g) {
  7751.          if (g == null) return; // Paranoia
  7752.          Dimension size = size();
  7753.          if (    offi == null
  7754.               || offi.getWidth()!=size.width
  7755.               || offi.getHeight()!=size.height  ) {
  7756.            if (offg!=null) offg.dispose();
  7757.            offi = createImage(size.width, size.height);
  7758.            offg = offi.getGraphics();
  7759.            // Regenerate offi here...
  7760.            }
  7761.          // If you use getClipBounds() here,
  7762.          // check that for being null, too!
  7763.          // several implementations have been known to pass them....
  7764.          g.drawImage(offi);
  7765.          }
  7766.  
  7767.        public void paint(Graphics g) {
  7768.          update(g);
  7769.          }
  7770.        }
  7771.  
  7772.      See also Question 8.7
  7773.  
  7774.   6. (Sect. 19) The dynamic type of a method argument doesn't seem to be
  7775.      used to choose an overridden method at runtime.
  7776.  
  7777.      [*] Correct. Generally, if you invoke a method on an object, the
  7778.      object's actual runtime type, not the type of the reference that you
  7779.      used to reference it, determines which method is invoked. This is
  7780.      regular polymorphism.
  7781.  
  7782.      It's not the same for object parameters: the compiler decides at
  7783.      compile time, depending on the types of the parameter expressions,
  7784.      which method signature to use, and this is "hardwired" into the
  7785.      bytecode. The compiler does not look at the object argument at runtime
  7786.      and say "ah, this is a derived type, so I will choose the method that
  7787.      takes the derived type as an argument."
  7788.  
  7789.      This is best seen in a code example:
  7790.  
  7791.      class Base { }
  7792.      class Derived extends Base { }
  7793.  
  7794.      public class foo {
  7795.  
  7796.         public static void method(Base b) {
  7797.           System.out.println("In the base method...");
  7798.         }
  7799.  
  7800.         public static void method(Derived d) {
  7801.           System.out.println("In the derived method...");
  7802.         }
  7803.  
  7804.         public static void test(Base b) {
  7805.           if (b instanceof Derived)
  7806.             System.out.print("Derived:  ");
  7807.           else
  7808.             System.out.print("Base:     ");
  7809.  
  7810.           method(b);   // which method?  method(base) or method(derived)?
  7811.         }
  7812.  
  7813.         public static void main(String args[]) {
  7814.           Base b = new Base();
  7815.           Derived d = new Derived();
  7816.  
  7817.           System.out.println("test calls.");
  7818.           test(b);
  7819.           test(d);
  7820.         }
  7821.      }
  7822.  
  7823.      Running the program gives an output of
  7824.  
  7825.      test calls.
  7826.      Base:     In the base method...
  7827.      Derived:  In the base method...
  7828.  
  7829.      See JLS section 15.11.4.4 and 15.11.3:
  7830.      "If class S contains a declaration for a method named m with the same
  7831.      descriptor (same number of parameters, the same parameter types, and
  7832.      the same return type) required by the method invocation as determined
  7833.      at compile time then this is the method to be invoked."
  7834.  
  7835.   7. (Sect. 19) Why did I lose my updates when I changed data fields in a
  7836.      graph that I was serializing?
  7837.  
  7838.      [*] Quoting from the object serialization specification at:
  7839.      http://www.javasoft.com/products/jdk/1.1/docs/
  7840.      guide/serialization/spec/serial-arch.doc.html#4176
  7841.           The writeObject method serializes the specified object and
  7842.           traverses its references to other objects in the object graph
  7843.           recursively to create a complete serialized representation of the
  7844.           graph.
  7845.  
  7846.           Within a stream, the first reference to any object results in the
  7847.           object being serialized or externalized and the assignment of a
  7848.           handle for that object. Subsequent references to that object are
  7849.           encoded as the handle.
  7850.  
  7851.      In other words, changing an object and then writing it again does not
  7852.      really write it twice. Instead it just writes a reference back to the
  7853.      first occurrence, losing any fields that have changed in the meantime.
  7854.  
  7855.      There are three ways around this: (1) (inefficient) Reset (or close and
  7856.      reopen) the stream, and start again by writing the new value of the
  7857.      object. This is drastic -- you are throwing away all the serialization
  7858.      that you have already done.
  7859.      (2) (kludgey) Create a new object and write that.
  7860.      (3) (could be a lot of work) Write your own protocol for object
  7861.      serialization. Have something like a data stream where the contents of
  7862.      an object are marked by special identifiers. Each "end" of the stream
  7863.      can decide whether it will use a new object each time or reuse an
  7864.      existing object.
  7865.  
  7866.   8. (Sect. 19) When I click on a Java window frame, it doesn't close!
  7867.  
  7868.      [*] You need to add the code to listen for a window closing event, and
  7869.      take the appropriate action (hide the window, exit the program if the
  7870.      top level frame, etc).
  7871.  
  7872.      The window closing event handler is simple:
  7873.  
  7874.      Frame mf = new Frame("binky");
  7875.      mf.addWindowListener( new WindowAdapter() {
  7876.          public void windowClosing(WindowEvent we) {
  7877.              System.exit(0); // or setVisible(false); etc.
  7878.          } });
  7879.  
  7880.      This really should be the default behavior of an AWT Frame. So you'll
  7881.      be delighted to hear that JavaSoft has "made it so" for the JFrame
  7882.      Swing component. That leads to a slightly different problem. See
  7883.      Question 4.3.3. See also Question 13.9.
  7884.  
  7885.   9. (Sect. 19) What's the deal with "super"? How far back into parent
  7886.      classes can I go?
  7887.  
  7888.      [*] The most common use of super is the call "super()" to invoke a
  7889.      constructor in the superclass. The keyword "super" is also used to
  7890.      access fields of any superclass (not just the immediate superclass)
  7891.      that are hidden by an identically named feature in the current class.
  7892.  
  7893.      However there is no way to "chain" several super's together, and reach
  7894.      back higher into the parent class hierarchy. E.g. do not think that
  7895.      "super.x" means the "x of parent" and "super.super.x" means the "x of
  7896.      grandparent". This is a very common mistake. There is no
  7897.      "super.super.x". Looking at the generated byte code, if you have
  7898.  
  7899.      class Parent {        }
  7900.  
  7901.      class Child extends Parent {       }
  7902.  
  7903.      then, in Child "super.someParentMethod();" means "invokespecial
  7904.      X.someParentMethod()" in the JVM, not "invokevirtual".
  7905.      Invokespecial means "call the exact method I am telling you."
  7906.      Invokevirtual means "call the right method for whatever object this
  7907.      is".
  7908.  
  7909.  10. (Sect. 19) When I change some component (e.g. a new label on a button)
  7910.      I don't see the change on the screen immediately even if I repaint().
  7911.  
  7912.      [*] You need to add these calls, instead of the repaint():
  7913.  
  7914.      invalidate();
  7915.      validate();
  7916.  
  7917.      They cause the component hierarchy to be marked as needing to be laid
  7918.      out again, and the validate causes that to be done. It may be
  7919.      expensive, but is always the most reliable way of getting the peers to
  7920.      recalculate size and to do what is needed to bring the display up to
  7921.      date.
  7922.  
  7923.  11. (Sect. 19) Why aren't popup menus working cross-platform for me?
  7924.  
  7925.      [*] On Windows, the pop-up trigger is a mouse release (except in
  7926.      certain programs like Netscape Communicator). On Unix, the pop-up
  7927.      trigger is a mouse press.
  7928.  
  7929.      Therefore you need to ask the question isPopupTrigger() in both the
  7930.      mousePressed() and mouseReleased() methods when implementing the
  7931.      MouseListener interface. Alternatively override Component's
  7932.      processMouseEvent as a central place for handling mouse input.
  7933.  
  7934.  12. (Sect. 19) Why aren't newlines working cross-platform for me?
  7935.  
  7936.      [*] Code like this:
  7937.  
  7938.      if (c == '\n')
  7939.           fin = true;
  7940.  
  7941.      is not cross-platform. On Unix the line terminator is "\n", on Windows,
  7942.      it is frequently "\r\n", on the Mac it is "\r".
  7943.  
  7944.      The call System.getProperty("line.separator") will return a string
  7945.      containing the platform-specific line separator character(s), and you
  7946.      then need to compare it according to how your data is formatted (e.g.
  7947.      compare 2 characters or one). There is also a property for the
  7948.      separator character in file pathnames, and other values too.
  7949.  
  7950.  13. (Sect. 19) Why didn't my text display in my GUI? Is the Inset wrong?
  7951.  
  7952.      [*] The most common Inset problem is not an Inset problem at all, but
  7953.      rather that people just assume the x,y location of a
  7954.      Graphics.drawString() actually refers to the top left part of the
  7955.      string image. In fact it refers to the baseline. So you'll need to take
  7956.      the font metrics into account:
  7957.  
  7958.      g.drawString("Hello World",0,getFontMetrics(getFont()).getAscent());
  7959.  
  7960.  14. (Sect. 19) Why did my polygon come out the wrong shape?
  7961.  
  7962.      [*] This question and answer comes directly off
  7963.      comp.lang.java.programmer, and deserves to be immortalized for
  7964.      posterity.
  7965.      When I use fillPolygon with the following points I get two inverted
  7966.      triangles instead of a rectangle. Why?
  7967.  
  7968.      int xPoints[] = {71, 78, 71, 78};
  7969.      int yPoints[] = {147, 147, 130, 130};
  7970.      g.fillPolygon(xPoints, ypoints, xPoints.length);
  7971.  
  7972.      Developer Felix Pahl supplied the answer in limerick form:
  7973.         o A developer (for details bored her)
  7974.           didn't follow the polygon's border
  7975.           so instead of right angles
  7976.           she got two triangles
  7977.           'cause the endpoints were in the wrong order!
  7978.  
  7979.      You must put the points in the order you would encounter them in if you
  7980.      went round the polygon's border. The filling algorithm is doing the
  7981.      right thing! Try drawing the points on paper to see:
  7982.  
  7983.      71,130   78,130
  7984.        O--------O
  7985.        |        |
  7986.        |        |
  7987.        |        |
  7988.        o--------o
  7989.      71,147   78,147
  7990.  
  7991.      Under JDK1.1, the two endpoints are connected automatically and you
  7992.      would order the array elements as:
  7993.  
  7994.      int xPoints[] = { 71,  78,  78,  71};
  7995.      int yPoints[] = {130, 130, 147, 147};
  7996.  
  7997.      Under JDK1.0.2, you have to explicitly connect the two endpoints, and
  7998.      you would write the array elements as:
  7999.  
  8000.      int xPoints[] = { 71,  78,  78,  71,  71};
  8001.      int yPoints[] = {130, 130, 147, 147, 130};
  8002.  
  8003.  15. (Sect. 19) Why can't I see all the components I added to a Frame?
  8004.  
  8005.      [*] If you have code like:
  8006.  
  8007.      Frame myframe = new Frame("Child Frame");
  8008.      myframe.resize(512,384);
  8009.      myframe.add(new Label("Child"));
  8010.      myframe.show();
  8011.  
  8012.      you may find that the Label does not show up in the Frame. Or it may
  8013.      show up in appletviewer, but not in a browser.
  8014.  
  8015.      The default layout manager for Frame is BorderLayout. Components
  8016.      positioned with a BorderLayout must include a positioning constant to
  8017.      be correct. So, change the add to
  8018.  
  8019.      myframe.add("Center", new Label("Child"));
  8020.  
  8021.      and all will be well.
  8022.  
  8023.  16. (Sect. 19) Why do I get the wrong results when I compare two Strings
  8024.      together?
  8025.  
  8026.      if (s1 == s2)
  8027.  
  8028.      is giving me funny results.
  8029.  
  8030.      [*] The comparison using "==" on objects, like Strings, is asking the
  8031.      question "do these two objects have the same reference?". That is, do
  8032.      they have the same address, and hence are not two object but one? What
  8033.      you most probably meant is "do these two Strings have the same
  8034.      contents?" which you can express this way:
  8035.  
  8036.      if ( s1.equals(s2) )
  8037.  
  8038.      This is a very, very easy mistake to make and impossible to spot until
  8039.      you have had it explained to you.
  8040.  
  8041.      People talk about "interning" a String. That means calling the intern()
  8042.      method on a String. This places the String in the runtime constant pool
  8043.      if it was not already there. The compiler is required to intern() all
  8044.      literal Strings. If you intern() all your Strings as well then all
  8045.      duplicates are shared and comparisons can be done by the (much faster)
  8046.      address comparison rather than content comparison. It's a performance
  8047.      optimization. See also Q3.22.
  8048.  
  8049.      Note that this comparison error also occurs with other objects, not
  8050.      just Strings. The code:
  8051.  
  8052.              if (getBackground() == Color.black)
  8053.  
  8054.  
  8055.      is a test for object identity, rather than content identity. It will
  8056.      work if you originally setBackground(Color.black). To avoid difficult
  8057.      debugging in the future, you almost certainly want to say
  8058.  
  8059.              if (getBackground().equals( Color.black ) )
  8060.  
  8061.  
  8062.      or even (in this visual case) compare the darkness of the RGB values of
  8063.      the pixels.
  8064.  
  8065.  17. (Sect. 19) Why doesn't final prevent my object from changing?
  8066.  
  8067.      [*] You have code like this
  8068.  
  8069.      final StringBuffer s = new StringBuffer("don't change me");
  8070.       // ...
  8071.      s.append(", but I did");
  8072.      System.out.println(s);
  8073.  
  8074.      And the new value of s is "don't change me, but I did". The reason is
  8075.      that the "final" modifier makes the reference variable (here, s) final,
  8076.      not the object that s points to. It means that the reference variable
  8077.      cannot be changed to point to some other StringBuffer. The state of the
  8078.      StringBuffer can still be modified by calling methods on it or directly
  8079.      assigning to its public fields.
  8080.  
  8081.      The right way to think about final is that it prevents you assigning to
  8082.      that particular variable. The only way to make the fields of an object
  8083.      constant (unchanging) is to make all its data fields private, and not
  8084.      provide any set methods for them, only get methods. Even that won't
  8085.      stop other objects of the same class adjusting it.
  8086.  
  8087.  18. (Sect. 19) Why can't the compiler find my package?
  8088.  
  8089.      [*] When trying to compile a file in a package you get a compiler error
  8090.      like:
  8091.  
  8092.       DBTest.java:10: Class database.Table not found in type declaration.
  8093.  
  8094.      The file Table.java and DBTest.java are in the same directory. They
  8095.      both have "package database;" at the top of the file. The current
  8096.      directory is included in the classpath.
  8097.  
  8098.      The reason is that when compiling packages, you have to be at the 'top'
  8099.      of the directory/package hierarchy. So to compile both Table.java and
  8100.      DBTest.java, you have to be in the directory that contains the database
  8101.      directory (i.e. where the package hierarchy starts), and just:
  8102.  
  8103.             javac database/Table.java
  8104.             javac database/DBTest.java
  8105.  
  8106.  
  8107.      and it should all compile fine.
  8108.  
  8109.  19. (Sect. 19) I have a program with keyboard input and a button. When the
  8110.      user hits the space bar, the button gets pressed as it is in focus!
  8111.  
  8112.      [*] The VM sets the focus on the first traversible object in the UI. If
  8113.      you want the button not to be assigned focus by default, you must
  8114.      subclass the button and override the isFocusTraversable() method to
  8115.      return false.
  8116.  
  8117.      Another approach is to manually set the focus on some other component
  8118.      (say the Frame) when you show the window. To do so you have to jump
  8119.      through hoops to outsmart the VM that is trying to set it on the
  8120.      button. One approach is to listen for the windowActivated event and set
  8121.      a Swing Timer to do a requestFocus() on the frame about 0.1 seconds
  8122.      after the activated message. This seems convoluted, but it is the only
  8123.      thing found that consistently works cross platform.
  8124.  
  8125.      Another reader suggests that if the frame normally gets the focus
  8126.      first, you can override its gotFocus() event and set the focus to the
  8127.      component you want. Don't forget to return true!
  8128.  
  8129.  20. (Sect. 19) What's the hidden size limitation of String serialization?
  8130.  
  8131.      [*] If you wish to Serialize a string, be alert to the restriction
  8132.      that:
  8133.           The size of the String, when UTF-encoded, must be < 64Kb
  8134.      So for robust code you have to examine the String once to ensure that
  8135.      it will be less than 64Kb after encoding, and then have the JVM
  8136.      effectively repeat that work in the process of encoding, when you write
  8137.      it to an ObjectOutputStream.
  8138.  
  8139.      A possible workaround that is to strip the string down to "byte[]" and
  8140.      pass it around in RMI that way. The code with this restriction is in
  8141.      DataOutputStream
  8142.  
  8143.          public final void writeUTF(String str)
  8144.          ...
  8145.          [perform the size-after-conversion-to-UTF computation]
  8146.          ...
  8147.              if (utflen > 65535)
  8148.                  throw new UTFDataFormatException();
  8149.          ...
  8150.  
  8151.      RMI relies on serialization, so RMI has the same String size
  8152.      limitation.
  8153.  21. (Sect. 19) When I change a field in just one object in my array, that
  8154.      field changes in all the objects in my array!
  8155.  
  8156.      [*] Here the problem is probably that you have initialized the array
  8157.      with N references to the same one object.
  8158.  
  8159.      This is easy to overlook, because arrays in Java only contain
  8160.      references to objects, not objects. (Or they can contain primitives).
  8161.      LI>(Sect. 19) Do DrawRect and FillRect work on rectangles of the same
  8162.      size?
  8163.  
  8164.      [*] No. java.awt.Graphics.drawRect draws a rectangle that's 1 pixel
  8165.      wider and 1 pixel taller than a rectangle drawn by fillRect.
  8166.  
  8167.                        -------------------------------
  8168.  
  8169. 20. Further Resources
  8170.  
  8171.   1. (Sect. 20) Are there any commercial/shareware/free Java libraries?
  8172.  
  8173.      [*] Take a look at the Java Collection Framework, a group of classes
  8174.      that are part of Java 1.2. These classes implement general-purpose data
  8175.      structures, and they will become widely used.
  8176.  
  8177.      The documentation for JDK 1.2 explains that the Collection Framework
  8178.      defines three kinds of things:
  8179.         o Standard interfaces representing data structures of various kinds
  8180.           for you to implement. Since these are interfaces, you can use them
  8181.           in your code before you have implemented them.
  8182.         o Partial implementations of those interfaces, saving you some work.
  8183.         o Complete implementations, ready to use for data in your programs.
  8184.  
  8185.      The standard interfaces are Collection, Set, List and Map, plus the
  8186.      more specialised SortedSet and SortedMap. Lists have duplicate elements
  8187.      whereas Sets do not. Finer distinctions such as immutability are
  8188.      defined in the implementor classes, enforced by throwing runtime
  8189.      exceptions. See the JDK 1.2 documentation for a full discussion. Also
  8190.      see http://byrden.com/java/Tree/index.shtml for a description of
  8191.      extending the collection framework, and a freeware class implementing
  8192.      trees.
  8193.  
  8194.      For more about sorting prior to JDK 1.2, look at the class SortDemo in
  8195.      the demo directory of the JDK. Alternatively, use one of the several
  8196.      classic sorts available from Roedy Green. They are supplied free with
  8197.      heavily commented Java source code.
  8198.  
  8199.      See "QuickSort", "HeapSort" and "RadixSort" in the Java glossary at
  8200.      http://mindprod.com/index.html.
  8201.  
  8202.      Also, try the Java Generic Library. This library (JGL) is freely
  8203.      downloadable from http://www.objectspace.com/
  8204.  
  8205.      Also Visual Engineering has JChart at: http://www.ve.com. No licensing
  8206.      fees.
  8207.  
  8208.      Visual Numerics has its Java Numeric Library available for download at
  8209.      http://www.vni.com/products/wpd/jnl/jnl_1_0.html. They offer the JNL as
  8210.      a proposed standard library for numerical functions missing from Java.
  8211.  
  8212.   2. (Sect. 20) Why doesn't somebody write a shell in Java? Then they could
  8213.      use it on all platforms!
  8214.  
  8215.      [*] Somebody has done just that. Look at http://www.jsh.net/
  8216.  
  8217.   3. (Sect. 20) Are there any URLs for other libraries?
  8218.  
  8219.      [*] Indeed, there are. The Java3D Repository http://java3d.sdsc.edu/
  8220.  
  8221.   4. (Sect. 20) Are there any URLs for regular expression handlers in Java?
  8222.  
  8223.      [*] There was one from ORO Inc, but they seem to have gone away. Their
  8224.      code, along with lots of other useful Java things is at
  8225.      http://web.theorem.com/java/index.htm
  8226.      For other sources, see
  8227.      http://Meurrens.ML.org/ip-Links/Java/regex/index.html
  8228.  
  8229.      And don't forget to check out Lava -- a set of Java classes designed to
  8230.      support programmers who develop console-mode applications and/or C
  8231.      programmers who are converting to Java. The first release of Lava has
  8232.      printf and other text formatting, encryption, parsing and miscellaneous
  8233.      I/O. Lava can be downloaded from http://www.newbie.net/sharky/lava/
  8234.  
  8235.      Also consider the Java version of the Unix find command. It offers
  8236.      Regex filename matching, mindepth, maxdepth, symlink follow / no
  8237.      follow, file type matching all cross-platform. The package is at
  8238.      http://www.geocities.com/~shecter/java.html
  8239.  
  8240.   5. (Sect. 20) Are there any installers for Java? Preferably
  8241.      platform-neutral ones.
  8242.  
  8243.      [*] There are several possibilities.
  8244.         o InstallAnywhere 2 from ZeroG software. See
  8245.           http://www.zerog.com/html/installanywhere_2.html
  8246.           They have a free version for shareware authors.
  8247.         o InstallShield makes a Java version of their installation package.
  8248.           See http://www.installshield.com/java/default.asp
  8249.         o IBM offers a comprehensive Java installer through its alphaworks
  8250.           site http//www.alphaworks.ibm.com/formula/installtoolkit
  8251.  
  8252.   6. (Sect. 20) What is "Jazilla"?
  8253.  
  8254.      [*] Jazilla is Mozilla (Netscape Communicator free source) ported to
  8255.      Java. In other words, a free source browser that supports Java and
  8256.      Javascript, written in Java!
  8257.  
  8258.      You can get more information, and volunteer to help with the project at
  8259.      http://www.jazilla.org/
  8260.  
  8261.   7. (Sect. 20) Where can I get Java for my Palm Pilot PDA?
  8262.  
  8263.      [*] There is a translator allowing you to compile Java programs for the
  8264.      Palm Pilot PDA! This is an astonishing piece of work as the Pilot has
  8265.      such a small memory footprint. The translator is in an early stage of
  8266.      development, but is available at:
  8267.      http://www.cs.washington.edu/homes/mcdirmid/ghost
  8268.  
  8269.      Try it, or even better, volunteer to help with the project. Details at
  8270.      the website above.
  8271.  
  8272.   8. (Sect. 20) What is "Dippy Bird" and where can I get it?
  8273.  
  8274.      [*] Dippy Bird is Java documentation in WinHelp format, which can be
  8275.      used directly on Windows desktops, and has a searching utility. The
  8276.      developer of the Dippybird project, Bill Bercik, has stopped further
  8277.      work on the project due to lack of time and funds. Instead you can use
  8278.      http://www.confluent.fr/javadoc/JavadocE.htm which has a more up to
  8279.      date Java WinHelp doc.
  8280.      You can get still get the Dippy Bird download at
  8281.      http://www.dippybird.com/jdk111.exe (JDK 1.1). Note that on NT 4.0 you
  8282.      need to change the generated shortcut to point to NT's 32-bit WinHelp.
  8283.  
  8284.   9. (Sect. 20) Where can I get icons for use with Java?
  8285.  
  8286.      [*] Public spirited programmer and Java supporter Dean S. Jones has
  8287.      created a collection of over 100 icons for use in Java freeware. They
  8288.      are available on the Java Lobby site at
  8289.      http://webart.javalobby.org/jlicons/.
  8290.  
  8291.  10. (Sect. 20) What the hell is "UML"?
  8292.  
  8293.      [*] UML is the Unified Modeling Language. It is unified in the sense
  8294.      that it draws together ideas from a couple of earlier software design
  8295.      languages. UML is an emerging standard for diagrams of object-oriented
  8296.      classes. It was devised by Grady Booch, Ivar Jacobsen, and James
  8297.      Rumbaugh, and it unifies several popular existing notations.
  8298.  
  8299.      UML is a product of Rational Software, who offer a tutorial CD for
  8300.      free. See http://www.rational.com/uml/tutorials2.html There are some
  8301.      whitepapers too, but there don't seem to be any free online tutorials.
  8302.  
  8303.      ObjectDesign Inc., has a UML designer written in 100% java. See
  8304.      http://www.objectdesign.com
  8305.  
  8306.  11. (Sect. 20) Where can I get info on Java college courses?
  8307.  
  8308.      [*] The JCampus site at http://www.jcampus.org has links and
  8309.      connections to Java CS Dept. courses, assignments, academic papers and
  8310.      Java-related events. JCampus is a non-profit, online Community for CS
  8311.      Dept. professors, students and staff who are teaching, learning and
  8312.      using the Java programming language.
  8313.  
  8314.  12. (Sect. 20) What is the Java IFAQ?
  8315.  
  8316.      [*] It is the Java list of Infrequently Answered Questions, a FAQ
  8317.      maintained by Peter Norvig, author of the book "Artificial Intelligence
  8318.      - A Modern Approach". Take a look at the Java IFAQ at
  8319.      http://www.norvig.com/java-iaq.html There's a lot of good information
  8320.      in that document.
  8321.  
  8322.  13. (Sect. 20) Are there any Java tools for PDF?
  8323.  
  8324.      [*] PDF (Portable Document FOrmat) is the text publishing format
  8325.      defined by Adobe. Acrobat is the technology to display and print PDF
  8326.      files. Abode supplies the client (document reading) software for free.
  8327.      There is a PDF toolkit written in Java at http://www.etymon.com. Even
  8328.      better it is GPL'd. It is more a toolkit for programmers embedding PDF
  8329.      in their products, than an end-user technology though. It doesn't have
  8330.      a GUI for displaying PDF for example.
  8331.  
  8332.  14. (Sect. 20) Are there any Java info search tools?
  8333.  
  8334.      [*] IBM has a very good search engine for java developers
  8335.      http://www.ibm.com/java
  8336.  
  8337.  15. (Sect. 20) What other languages compile to bytecode?
  8338.  
  8339.      [*] Quite a lot of languages compile to Java bytecode, more than 60 at
  8340.      the last count. See the webpage
  8341.      http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html
  8342.  
  8343.  16. (Sect. 20) Has anyone written a Java-to-RPC interface, to talk to
  8344.      legacy code?
  8345.  
  8346.      [*] See www.distinct.com. It implements a subset of RPC, and is a
  8347.      commercial, supported product. You can review RFCs 1831 and 1832 for
  8348.      information on the full protocol. Java uses the same endianness as
  8349.      RPC's external data representation (network byte order), so all the
  8350.      Java file reads/writes can be used directly.
  8351.  
  8352.      The specifications are in RFC 1831 (the RPC protocol spec) and RFP 1832
  8353.      (the XDR spec).
  8354.  
  8355.  17. (Sect. 20) Are there any automated tools for Javadoc?
  8356.  
  8357.      [*] Yes. See http://www.mindspring.com/~chroma/docwiz/docwizApplet.html
  8358.      for a Java development tool called DocWiz. It is the easiest way to add
  8359.      JavaDoc comments to your Java code.
  8360.  
  8361.                        -------------------------------
  8362.  
  8363. 21. Acknowledgements
  8364.  
  8365. A jolly little song that explains how to solve commonly-encountered problems
  8366. in Java.
  8367.  
  8368.                     The FAQ Melody
  8369.                   by Antranig Basman.
  8370.  
  8371. On the First Day of Christmas, my true-love said to me:
  8372. Read the F-A-Q.
  8373.  
  8374. On the Second Day of Christmas, my true-love said to me:
  8375. My Image isn't drawing;
  8376. Read the F-A-Q.
  8377.  
  8378. On the Third Day of Christmas, my true-love said to me:
  8379. My Pixels are not grabbing,
  8380. My Image isn't drawing,
  8381. Read the F-A-Q.
  8382.  
  8383. On the Fourth Day of Christmas, my true-love said to me:
  8384. My Layout is not laying,
  8385. Pixels are not grabbing,
  8386. Image isn't drawing,
  8387. Read the F-A-Q.
  8388.  
  8389. On the Fifth Day of Christmas, my true-love said to me:
  8390. Null - Pointer - Exception!
  8391. My Layout is not laying,
  8392. Pixels are not grabbing,
  8393. Image isn't drawing,
  8394. Read the F-A-Q.
  8395.  
  8396. On the Sixth Day of Christmas, my true-love said to me:
  8397. Netscape will not run it,
  8398. Null - Pointer - Exception!
  8399. Layout is not laying,
  8400. Pixels are not grabbing,
  8401. Image isn't drawing,
  8402. Read the F-A-Q.
  8403.  
  8404. On the Seventh Day of Christmas, my true-love said to me:
  8405. J++ don't mind it,
  8406. Netscape will not run it,
  8407. Null - Pointer - Exception!
  8408. Layout is not laying,
  8409. Pixels are not grabbing,
  8410. Image isn't drawing,
  8411. Read the F-A-Q.
  8412.  
  8413. On the Eighth Day of Christmas, my true-love said to me:
  8414. Threads they are a-blocking,
  8415. J++ don't mind it,
  8416. Netscape will not run it,
  8417. Null - Pointer - Exception!
  8418. Layout is not laying,
  8419. Pixels are not grabbing,
  8420. Image isn't drawing,
  8421. Read the F-A-Q.
  8422.  
  8423. On the Ninth Day of Christmas, my true-love said to me:
  8424. Dialogs-a-hanging,
  8425. Threads they are a-blocking,
  8426. J++ don't mind it,
  8427. Netscape will not run it,
  8428. Null - Pointer - Exception!
  8429. Layout is not laying,
  8430. Pixels are not grabbing,
  8431. Image isn't drawing,
  8432. Read the F-A-Q.
  8433.  
  8434. On the Tenth Day of Christmas, my true-love said to me:
  8435. Time-zone's in Pacific,
  8436. Dialogs-a-hanging,
  8437. Threads they are a-blocking,
  8438. J++ don't mind it,
  8439. Netscape will not run it,
  8440. Null - Pointer - Exception!
  8441. Layout is not laying,
  8442. Pixels are not grabbing,
  8443. Image isn't drawing,
  8444. Read the F-A-Q.
  8445.  
  8446. On the Eleventh Day of Christmas, my true-love said to me:
  8447. Docs are not specific,
  8448. Time-zone's in Pacific,
  8449. Dialogs-a-hanging,
  8450. Threads they are a-blocking,
  8451. J++ don't mind it,
  8452. Netscape will not run it,
  8453. Null - Pointer - Exception!
  8454. Pixels are not grabbing,
  8455. Image isn't drawing,
  8456. Read the F-A-Q.
  8457.  
  8458. On the Twelfth Day of Christmas, my true-love said to me:
  8459. File I/O's horrific,
  8460. Docs are not specific,
  8461. Time-zone's in Pacific,
  8462. Dialogs-a-hanging,
  8463. Threads they are a-blocking,
  8464. J++ don't mind it,
  8465. Netscape will not run it,
  8466. Null - Pointer - Exception!
  8467. Layout is not laying,
  8468. Pixels are not grabbing,
  8469. Image isn't drawing;
  8470.  
  8471. You Should Read The-e F-A-Q!
  8472.  
  8473. FAQ copyright 1997, 1998 by Peter van der Linden. Contributions and help
  8474. from:
  8475.  
  8476. Matt Kennel, Patric Jonsson, Brad Van Tighem, Tony Hursh, Glenn L
  8477. Vanderburg, Peter Jones, John McDowall, Jim Driscoll, Uday, Dave Harris,
  8478. Bill Wilkinson, Tom Valesky, Dan Drake, Giles Thomas, Mitch Baltuch, Guy
  8479. Ruth Hammond, Gordon Keith, Jason Brome, Shani Kerr, Steve Chapel, Timothy
  8480. Wolters, Robert Lynch, Jake Cormier, Sean C Sullivan, Joseph A. Millar, Jim
  8481. Frost, Jim Balter, Jeff Bauer, John Kochmar, Carl Burke, William Stubbs,
  8482. Mark Smith, Volker Turau, Real Gagnon, Russell Gold, Max Hailperin, Bill
  8483. Tschumy, Marco Nijdam, Marc Pawlowsky, Laurence Vanhelsuwe,Ian Macgregor,
  8484. Mike Faulkner, Rich Koch, Will Clark, Govind Seshadri, Rich Simkin, Ian
  8485. Stiles, Kieren, Darren Christie, Tom Lane, Michael Jungmann, Rob Mayoff,
  8486. George Ruban, Tom McCann, David Hopwood, Thomas Phan, Kai Stuke, Rolf
  8487. Howarth, Derek Snider, David Boydston, Andy Godwin, John F. Dumas, Doug
  8488. Bell, David J. Biesack, Tiger Quimpo, Martin Hugh Rogers, Brian Krahmer, Ian
  8489. Burrell, Nikki Locke, Bin Li, Jackson Thompson, Steve Odendahl, Greg Smith,
  8490. Jeffrey C. Ollie, Mark Halvin, Jeremy Cook, Lak Ming Lam, Peter S. Morris,
  8491. Mark Halvin, Juergen Keil, Alex Stewart, Mike Abney, Rodney Stephenson, Mark
  8492. Gritter, Satish Talim, Tamminen Eero, Alexander Gridnev, Eric Hodges, Jamey
  8493. Graham, Will Lockhart, Scott Plante, Tom Sanfilippo, Jan Newmarch, Sean
  8494. Breslin, Stuart D. Gathman, rhino@wwdc.com, C Matthew Curtin, Tor Iver
  8495. Wilhelmsen, A.N.Pryke, Phil Race, David Holmes, David Rodal, Dominique
  8496. Plante, Trent Jarvi, Ingrid Biery, Gopal Unni Krishnan, Grant Lewis, Tov Are
  8497. Jacobsen, Gary McGath, Marty Hall, Will Forster, Colin Mummery, Darin
  8498. McBride, Mayank Shah, Jens Alfke, Glen Stampoultzis, Philip Brown, Peter
  8499. Steiner, Kurt Spaugh, Rasmus Ekman, Jonathan Revusky, Ken Kalish, Dave
  8500. Sanders, Bill Hyden, James Cloughley, Philip "diodes" Gustafson, Paul
  8501. Kinnucan, Juan Valdéz, Antranig Basman, Felix Pahl, David N. Still, Simon
  8502. Arthur, Mark Hammond, Dan Kegel, Thomas Weidenfeller, Pavel Shvartsman,
  8503. Christen Monberg, George Reese, Ian Macgregor, John Sublett, David
  8504. Zimmerman, Tony Dahlman, Druid, Chris Kelly, Patricia Shanahan, Paul Hill,
  8505. Lyne Lamoureux, Don Kennedy, Alec Muffett, Andrew Mickish, Pavel Shvartsman,
  8506. Neil of Parkway Consultants, Chris Thiessen, David Michaels, Bob Sutherland,
  8507. Michael Allen Latta, Joshy, Eric Albert, Wes Isberg, Lisa Retief, Michael
  8508. Park, Dave Postill, Thomas Weidenfeller, Konstantin Laufer, Håkan
  8509. Gustavsson, James Stauffer, Reuben Firmin, David Lim, Eamonn Maher, Craig
  8510. West, Pavel Shvartsman, Jay Dunning, Kevin Swan, Grant Gainey, Dan Schmitt,
  8511. Benjamin Goldberger, Jake Hamby, Yaakov Itzhaki, Robert Lynch
  8512.  
  8513. ------------------------------------------------------------------------
  8514.  
  8515. I am maintaining a FAQ list to address specifically programming issues
  8516. (not a general tutorial on Java). Please mail suggested FAQ entries
  8517. including answer to faqidea on the site afu.com.
  8518. Question with answer gets you a credit in the FAQ.
  8519. Peter van der Linden, Sun Certified Java Programmer.
  8520. ------------------------------------------------------------------------
  8521.  
  8522. Cross references
  8523.  
  8524. Most cross reference links inside this document are still to be filled in
  8525. after the great FAQ re-org. If you'd like to contribute a few, send me the
  8526. new text for the NAME= and the HREF=, and I'll fold them in as time permits.
  8527. Look at the FAQ source for the style to follow.
  8528.  
  8529. Copyright
  8530.  
  8531. Copyright (c), 1997,1998 Peter van der Linden. Permission to copy all or
  8532. part of this work is granted for individual use, and for copies within a
  8533. scholastic or academic setting. Copies may not be made or distributed for
  8534. resale. The no warranty, and copyright notice must be retained verbatim and
  8535. be displayed conspicuously. You need written authorization before you can
  8536. include this FAQ in a book and/or a CDROM archive, and/or make a
  8537. translation, and/or publish/mirror on a website (scholastic and academic use
  8538. excepted). If anyone needs other permissions that aren't covered by the
  8539. above, please contact the author.
  8540.  
  8541. No Warranty
  8542.  
  8543. This work is provided on an "as is" basis. The copyright holder makes no
  8544. warranty whatsoever, either express or implied, regarding the work,
  8545. including warranties with respect to merchantability or fitness for any
  8546. purpose.
  8547.  
  8548. ------------------------------------------------------------------------
  8549.